Asp.NET中弹出窗口

     写了很久的Winform,简单的探出对话框处理一直都没有引起什么注意,最近加到一个Asp.NET项目组,虽然对于从Winform到Web会比较麻烦这点早就有所觉悟的,但是没有想到的是第一只拦路虎居然就是探出对话框。主要遇到的麻烦就是:
一、弹出消息框的时候,线程并不会阻塞等待对话框的确认,而是直接就执行下去了。尤其是在弹出确认对话框后进行页面跳转的时候,没来得及探出对话框就直接执行跳转了。
二、使用Ajax的页面直接灸无法正常弹出提示框来。
 没办法,网上调查了一下,再向同事们请教,总结出了这么些个项目中常用的方法。
 
作为 Microsoft 的最新建立动态 Web 网站的工具, ASP.NET 相对于 ASP JSP 在改变原始的 Web 编程方式方面有了长足的长进。它的代码与页面分离技术( CodeBehind )以及完善的 Web服务器 控件为 程序 员提供了一个更加符合传统编程的 Web 服务器端开发方式。但 Web 编程还是有着与传统编程不相同的特点,这些特点决定了 ASP.NET 编程中必须以一些特殊的技巧来完成程序要求,弹出窗口正是这类编程方式的代表。相当多的编程书籍对弹出窗口采取缄默或者一语带过,似乎看不过弹出窗口的巨大使用天地。本文将为你解开弹出窗口使用中的大多数问题。

  为了提高网站的访问的并发度和吞吐量,与其它服务器脚本一样, ASP.NET 同样使用了客户端脚本来减轻服务器的压力。 ASP.NET 到现在 (1.1 ) 为止并不直接支持弹出窗口,必须通过 JavaScript (或 VBScript )来使用客户端弹出窗口。

  一、 警告窗口与在 CodeBehind 中使用客户端脚本的方式

  要在浏览器中弹出一个最简单的警告窗口,可以使用 JavaScript 语句:
window.alert( [sMessage])

Private Sub btAlert_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btAlert.Click
  演示 Response.Write 方法和 alert 窗口。
  Response.Write(" ")
End Sub

Overridable Public Sub RegisterStartupScript( _
  ByVal key As String, _
  ByVal script As String _
)

Private Sub btConfirm_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btConfirm.Click

  演示 RegisterClientScriptBlock 方法和 confirm 窗口

  If (Not IsClientScriptBlockRegistered("clientScript")) Then
  判断是否已经加入了该脚本,没有则加入。
   Dim strScript As String
   strScript = " "
  注册脚本
   RegisterClientScriptBlock("clientScript", strScript)
  如果选择 ,则继续向下执行。
  End If

End Sub
  二、 弹出指定页面

  光有提示窗口还远远不能满足我们的要求,在程序中,我们常常需要弹出指定页面。此时可以使用 JavaScript window.open 方法。配合前面的 RegisterClientSciptBlock 方法,我们就可以实现指定页面的弹出。

  以下代码展示了如何弹出指定页面 :
Private Sub btWinOpen_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btWinOpen.Click

  使用 window.open registerStartupScript 简单演示。

  If (Not IsClientScriptBlockRegistered("OpenScript")) Then
   判断是否已经加入了该脚本,没有则加入。
   Dim strScript As String = " "
   RegisterStartupScript("OpenScript", strScript)
  End If
End Sub
程序使用 Window.open 方法来弹出新的页面,它只一个参数:新的弹出窗口的 URL 地址。事实在 window.open 方法有多个参数,但这是 javascipt 的简单内容,我们将不会在这儿详细分说。如果你有相关的问题,请查询 MSDN

  这段程序在 IE 中直接使用一切正常。但如果你正在使用类如 GoSurf MyIE2 NetCapter 之类的浏览器,那么,很不幸! 你将看不到弹出窗口。这就是我们将要讨论的弹出窗口过滤问题。

  三、 非标准 IE 浏览器对弹出窗口的过滤行为讨论

  广告窗口的泛滥使得不少网民不堪铺天盖地的广告骚扰纷纷放弃标准 IE 浏览器而使用诸如 GoSurf MyIE2 NetCapter 这样的使用 IE 内核支持多页面并能自动屏蔽广告的 软件 。据说在即将发布的 IE6 sp2 微软 也将加入封杀广告窗口功能。这对大多数网民当然是件好事,可对于程序员而言,我们使用弹出窗口的方式与一般广告并无本质的不同,这样的窗口也会被弹出窗口管理器不分青红皂白的封杀,其结果当然是我们不愿看到的。有没有一个标准的方式能让窗口正常的弹出呢?这就要求我们了解浏览器封杀广告的原理。通常的广告封杀器使用以下三种方式进行广告过滤:

  ( 1 )、基于窗口标题的封杀方式

  这种封杀方式的原理是定时检查所有的 IE 窗口标题 , 然后于已经有的列表(由程序维护的一个数组列表)来比较 , 如果有相同的 , 我们就关闭这个窗口。显然,这种方式有着诸多缺陷,它封杀了所有的弹出的窗口,管得太死,在程序真正使用的很少。不过,依据它进行的变形方式倒使用得相当的普遍。那就是,基于窗口标题名称的智能过滤技术,它根据弹出窗口的标题是否含有关于广告的关键字进行封杀,这为提高过滤效果作出了很好的探索。

  ( 2 )、基于窗口类和位置的封杀方式

  经过分析发现正常浏览窗口的类名是 IEFRAME CabinetWClass, 而广告窗口的类名是 CabinetWClass 。进一步分析发现:广告窗口的 WorkerA 类和 Shell DocObject View 类的 rect.top 的值是相同的,正常 IE 窗口的 WorkerA 类和 Shell DocObject View 类的 rect.top 的值是不相同的。根据以上两点就可以书写广告杀手程序了。 事实上,我对此程序的通用性持怀疑态度。因为笔者用 Spy++ 分析发现,在 Windows2000( 笔者使用的操作系统 ) 中, IE 窗口的类都为 IEFrame 。同时,由于 Win2000 是一个基于 Unicode 代码的操作系统,所以没有 WorkerA 类,而以 WorkerW 类取而代之。同时,也不存在 rect.top 不相同的情况,由于笔者没有 WindowsXP 操作系统,所以不能针对 WindowsXP 作进一步的试验。

  ( 3 )、基于 IE COM 组件的封杀方式

  以上两种方式都是把 IE 窗口当作一个普通的 Windows 窗口对待,进行判断的。事实上, IE 是一个典型的基于 COM 组件的浏览器,所有的基于 IE 内核的浏览器都是包装 shdocvw.dll 文件,然后书写相应的 BHO 代码。只有这样才能做到真正的控制 IE 浏览器,而不是方法一、二这样的隔靴搔痒。

  还有一种基于 IE 内核的弹出窗口封杀方法。它可以在弹出窗口打开之前加以拦截。其原理是:每当 IE 打开一个新的窗口时候都会触发 NewWindow 事件,执行 OnNewWindow2([out] IDispatch*, [out] BOOL *bCancel) 方法。重载此方法,判断打开新窗口事件是否发生在浏览页面已经 下载 完毕之后。如果是,说明是正常的弹出窗口,反之加以拦截。

  由于 Gosurf 这样的浏览器本身就重载了 Shocvm.dll 组件,所以使用第三种方法就自然成了顺理成章的事。然而在使用过程中有时也会发现,广告过滤不很完美,但原理基本如此。
 
一些总结的例子:

1、    点击按钮确定取消

   page_load里加入bt_Del.Attributes["onclick"]="javascript:return  confirm('确认删除?')";

2、    需要弹出提示对话框后跳转到页面

   Response.Write("<script>alert('注册成功!');location.href='userlogin.aspx';</script>");

3、    允许 ASP.NET 服务器控件在 Page 中发出客户端脚本块:
    public virtual void RegisterStartupScript(string key,string script);

    举例如下:
    if(!this.IsStartupScriptRegistered("hello"))
        this.RegisterStartupScript("hello"," <script type="text/javascript"> </script>");  

 

        #region 弹出信息框提示

        #region 同步事件触发的弹出消息框

        public static string ShowMessageBox(Page p_pPage, string IMessageId)

        {

            string rtStr = string.Empty;

            string messageString;

            messageString = ConfigurationManager.AppSettings["MSG_COM_" + IMessageId];

            string categoryId = IMessageId.Substring(0, 2);

            p_pPage.RegisterStartupScript("ErrorInfo", "<script>alert('" + messageString + "');</script>");

            rtStr = messageString;

            return rtStr;

        }

        #endregion

 

        #region 异步事件触发的弹出消息框

        public static string ShowAsyncMessageBox(UpdatePanel p_oUpdatepanel, string IMessageId)

        {

           

            string rtStr = string.Empty;

            string messageString;

            messageString = ConfigurationManager.AppSettings["MSG_COM_" + IMessageId];

            string categoryId = IMessageId.Substring(0, 2);

            ScriptManager.RegisterClientScriptBlock(p_oUpdatepanel, p_oUpdatepanel.GetType(), "", "alert('" + messageString + "')", true);

            rtStr = messageString;

            return rtStr;

        }

 

        #endregion

        #endregion

 

  其中:key表示这个脚本的唯一标识,script是代表脚本的字符串。

  RegisterClientScriptBlock的原型与RegisterStartupScript相同,两个函数不同在于将其包含的脚本代码写入到HTML文件的不同位置。RegisterClientScriptBlock Page 对象的元素的开始标记后立即发出客户端脚本,RegisterStartupScript则是在Page 对象的元素的结束标记之前发出该脚本。如果你的脚本有与页面对象(doucument对象)进行交互的语句(这在我们后面的例子中看到),则推荐使用RegisterStartupScript,反之如果要想客户端脚本尽可能早的执行,则可以使用RegisterClientScriptBlockResponse.Write

  为了防止在页面中反复加入脚本,在注册脚本时ReisterStartupScript/RegisterClientScriptBlock使用了key作为注册的Key,然后在程序中可以使用IsClientScriptBlockRegistered作判断。

  以下例子将使用RegisterClientScriptBlock来演示confirm的使用方法。
  (2使用RegisterXXX方法

  如果你观察Response.Write的生成HTML代码,你会发现Response.Write方法生成的代码是写到了HTML代码的最开始,即标签之前。此时,所有的 HTML对象都还没有生成,如果要想使用HTML内的对象,并与之交互,就会出现找不到对象的错误。因此,笔者推荐一个更加符合CodeBehind方式的方式----使用RegisterXXX方法。RegisterXXX包括:RegisterClientScriptBlockRegisterStartupScript以及用于判断的IsStartupScriptRegistered函数。

  RegisterStartupScript 的原型是:
  其中, sMessage 是提示信息。可惜,这样的弹出窗口是只有一个 确定 按钮,只能起到提示作用。如果我们要在删除记录时候弹出一个询问的弹出窗口,此时你需要使用:

bConfirmed = window.confirm( [sMessage])

  其中: bConfirmed 是返回值, sMessage 是提示信息。这个弹出窗口有两种选择: 确定 放弃 ,其选择的返回值放在 bConfirmed 中,可供代码作出判断。

  为了提高代码的可重用性与可读性,应当使 JavaScript Codehind 相互溶合。通常有两种方式可以达到这样的效果。

  ( 1 使用 Response.Write 方法:

  使用 Response.Write 方法早在 ASP 时代就已经被支持了。它可以把代码写到客户端,是一种相当方便且直观的方法。以下代码演示了如何使用 Response.Write 方法来显示一个警告信息。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值