很多时候,我们在WEB项目中需要用到弹出对话框形式的页面,做为子页面辅助父页面进行操作。习惯下常会用到2种方式,一是可以通过Window.showmodaldialog 函数弹出页面,二是可以通过自写脚本,弹出div,在div里面嵌套iframe实现。
两种方式的区别是第一种方式打开的是个模态窗口,他将做为父窗口执行时间的一部分执行,在模态窗口(子窗口)打开时,父窗口的动作将会阻塞在此,等模态窗口关闭后,父窗口动作再继续执行,而且它会有个返回值window.returnValue。但是在模态窗口下,页面里面的内容是不能复制的,造成了很大的不便。第二种方式弹出就是一个平常的页面调用,页面里的内容能任意复制(如果要输入的数据量大而且重复的时候此功能尤显重要)。
两种方式的使用各有各的特点:
一、 父窗口中点击一个服务端按钮,希望先执行客户端代码,验证通过后再提交服务器以刷新数据,如果验证业务逻辑较复杂,需要借助子窗口辅助验证,就可以采用第一种方式,弹出模态窗口,先阻塞父窗口动作,等子窗口验证完成,关闭窗口且返回 window.returnValue值,父窗口继续执行,根据子窗口返回的window.returnValue值判断是否需要提交刷新,而且用此方式提交是有状态提交(就是说如果你的页面是分页的第二页,这样提交后刷新你还是在分页的第二页)。
二、 父窗口不需要根据子窗口的返回值来判断是否需要提交刷新的情况下,可以采用第二种方式弹出子窗口。因为自写脚本div弹出的方式不能阻塞父窗口动作,所以父窗口不能等待接受子窗口执行完毕返回的值,也就不能根据返回的值来决定是否提交刷新。但是子窗口里面的内容能随意复制,体验度较第一种好。如果你要关闭子窗口后,刷新父窗口页面也一般采用 window.location.reload 函数刷新,不过这样刷新的方式是页面重新加载,父窗口所有状态消失(就是说你的页面是分页的第二页,这样刷新后你就又回到第一页了)。
以下提供一个结合以上二种方式的使用的第三种方式:
以div方式弹出子窗口,在业务逻辑执行完成后,如果验证通过,就在子窗口中用脚本先找到父窗口页面对象,如parent,调取父窗口页面中的form提交方法submint(),实现有状态回发。
子窗口运行脚本如下:
Parent.document.forms['form1'].__EVENTTARGET.value ;
Parent.document.forms['form1'].__EVENTARGUMENT.value = Parent.document.forms['form1'].submit();
“Parent” 代表父窗口,(要自己编写获取对象的脚本)
“forms['form1']” 代表父窗口中要提交的form对象
“__EVENTTARGET” 代表要模拟父窗口中用来提交form的服务端控件的name属性
“__EVENTARGUMENT” 代表父窗口中要提交form传递的值
“forms['form1'].submit()” 执行父窗口中form的提交动作
子窗口业务逻辑处理完成后,执行以上脚本,父窗口将会实现有状态提交刷新,而且子窗口页面中的内容能随意复制。并且使用此方法提交可以绕过父窗口控件的客户端验证(如Button的“OnClientClick”事件),直接提交服务器。
回过来查看父窗口的html源码,会发现有以下几行代码
<script type="text/javascript">
//<![CDATA[
var theForm = document.forms['form1'];
if (!theForm) {
theForm = document.form1;
}
function __doPostBack(eventTarget, eventArgument) {
if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
theForm.__EVENTTARGET.value = eventTarget;
theForm.__EVENTARGUMENT.value = eventArgument;
theForm.submit();
}
}
//]]>
</script>
这是ASPX.NET自动在aspx页面生成的用来提交form的隐藏脚本,借助此段脚本,就能实现有状态提交刷新的功能。
所以如果要使用这种方式就要注意几点:
1、 父窗口页面需要是aspx页面
2、 父窗口页面上要有“id=__EVENTTARGET”和“id=__EVENTARGUMENT”的2个隐藏对象(系统自动生成),在有些页面上没有,可以在页面上添加LinkButton按钮,系统就会自动生成,所以你可以添加个按钮,用“style=’display:none;’”,隐藏掉)如图:
图1:系统自动生成的2个隐藏控件
图2:父窗口(aspx页面)隐藏的LinkButton控件