returnValue of Chrome
说实话,我一看到这个returnValue
就有点反感,感觉这个就是IE式的老套的用法,因为项目中有用到就了解了下,以下主要是一些我的理解和发现吧。
PS:returnValue
是window
的属性,showModalDialog
和open
是window
的方法。
returnValue
是与showModalDialog
搭配使用的,showModalDialog
用于打开窗口,与open
类似效果,但通过showModalDialog
打开窗口时有如下特点:
- 打开窗口后,将不能再操作父窗口了(正常情况下,父窗口将获取不到焦点了);
- 确切的说父窗口在执行
showModalDialog
这一步时停止了,等待子窗口操作返回,而showModalDialog
之后的js代码也就暂时不会执行了; - 而
returnValue
就是返回值,子窗口通过window.returnValue
将操作结果返回给父窗口,在子窗口调用window.close
方法后,returnValue
将作为showModalDialog
的返回值传递到父窗口中,之后继续执行showModalDialog
后面的js代码;
网上的搜罗了下,都说IE、Firefox支持的,而Chrome虽然有showModalDialog
方法,但效果仅仅类似open
,且不支持returnValue
,至于Opera则完全不支持(应该说的不是Webkit内核的Opera)。
初步写代码测试了下(只测IE、Firefox、Chrome),我写了三个页面,主要逻辑是:t1中打开t2、t2中打开t3、同时每个页面上添加点击测试、刷新测试按钮(用于Chrome测试),基本html代码如下,可直接点击页面地址进行浏览:
t1.html代码:
- <!doctype html>
- <html>
- <meta charset="utf-8"/>
- <title>t1</title>
- <script>
- alert("load t1");
- function openT2(){
- alert(showModalDialog('t2.html',{msg:"arguments from t1.html",win:window},''));
- alert('子窗口已关闭');
- }
- function openT1Self(){
- alert(showModalDialog('t1.html',{msg:"arguments from t1.html",win:window},''));
- alert('子窗口已关闭');
- }
- function closeSelf(){
- window.returnValue='从t1正常返回的returnValue';
- window.close();
- }
- if(window.dialogArguments){
- if(window.dialogArguments.msg){
- alert(window.dialogArguments.msg);
- }else{
- alert(window.dialogArguments);
- }
- }
- function reloadPage(){
- alert('before');
- window.location.reload();
- alert('after');
- }
- function setReturnValue(){
- var str = prompt("请输入returnValue值")
- window.returnValue = "t1在刷新前所赋的returnValue:"+str;
- alert("赋值完毕,请点击刷新!");
- }
- </script>
- <body>
- <a href="javascript:openT2();">打开t2</a>
- <a href="javascript:openT1Self();">打开t1自己</a>
- <a href="javascript:closeSelf();">关闭</a>
- <a href="javascript:alert('点击了');">Chrome下点击测试</a>
- <a href="javascript:setReturnValue();">在刷新前给returnValue赋值</a>
- <a href="javascript:reloadPage();">点击刷新</a>
- </body>
- </html>
t2.html代码:
- <!doctype html>
- <html>
- <meta charset="utf-8"/>
- <title>t2</title>
- <script>
- alert("load t2");
- function openT3(){
- alert(showModalDialog('t3.html',{msg:"arguments from t2.html",win:window},''));
- alert('子窗口已关闭');
- }
- function closeSelf(){
- window.returnValue='从t2正常返回的returnValue';
- window.close();
- }
- if(window.dialogArguments){
- if(window.dialogArguments.msg){
- alert(window.dialogArguments.msg);
- }else{
- alert(window.dialogArguments);
- }
- }
- function reloadPage(){
- alert('before');
- window.location.reload();
- alert('after');
- }
- function setReturnValue(){
- var str = prompt("请输入returnValue值")
- window.returnValue = "t2在刷新前所赋的returnValue:"+str;
- alert("赋值完毕,请点击刷新!");
- }
- </script>
- <body>
- <a href="javascript:openT3();">打开t3</a>
- <a href="javascript:closeSelf();">关闭</a>
- <a href="javascript:alert('点击了');">Chrome下点击测试</a>
- <a href="javascript:setReturnValue();">在刷新前给returnValue赋值</a>
- <a href="javascript:reloadPage();">点击刷新</a>
- </body>
- </html>
t3.html代码:
- <!doctype html>
- <html>
- <meta charset="utf-8"/>
- <title>t3</title>
- <script>
- alert("load t3");
- function closeSelf(){
- window.returnValue='从t3正常返回的returnValue';
- window.close();
- }
- if(window.dialogArguments){
- if(window.dialogArguments.msg){
- alert(window.dialogArguments.msg);
- }else{
- alert(window.dialogArguments);
- }
- }
- function reloadPage(){
- alert('before');
- window.location.reload();
- alert('after');
- }
- function setReturnValue(){
- var str = prompt("请输入returnValue值")
- window.returnValue = "t3在刷新前所赋的returnValue:"+str;
- alert("赋值完毕,请点击刷新!");
- }
- </script>
- <body>
- <a href="javascript:closeSelf();">关闭</a>
- <a href="javascript:setReturnValue();">在刷新前给returnValue赋值</a>
- <a href="javascript:reloadPage();">点击刷新</a>
- </body>
- </html>
测试1
直接将t1.html文件拖入浏览器浏览进行测试。
测试结果:
- IE、Firefox没有问题;
Chrome下则
returnValue
几乎无效,具体细节:showModalDialog
效果接近open
,即只是打开了一个新窗口而已,父窗口仍然可以操作,而showModalDialog
后的语句没有执行,但控制台上却有些信息提示,有一个警告(灰色)和错误(红色):Chromium is considering deprecating showModalDialog. Please use window.open and postMessage instead.
Uncaught SecurityError: Blocked a frame with origin "null" from accessing a frame with origin "null". Protocols, domains, and ports must match.
警告信息表明Chromium将弃用
showModalDialog
(经验证,在Chromium38.0.2074.0中,showModalDialog
已报undefined
错误,看来已被遗弃,见官方Issue345831,不知Chrome之后会不会如此……)。错误信息是在关闭子窗口后出来的,这个就是说明了为什么
returnValue
无效以及showModalDialog
后面的语句为什么没执行(报错了么,呵呵),这个错误似乎跟跨域访问有点类似啊。PS:在较老版本的Chrome中并不会有这里的警告及错误信息,故可能让人误以为不支持
returnValue
PPS@2014/09/14: 最近无意间在Firefox(版本号是32)的控制台也看到类似的提示信息,如下所示,看来
ShowModalDialog
的结局可想而知了。window.showModalDialog() 已废弃。请使用 window.open() 代替。更多信息见 https://developer.mozilla.org/en-US/docs/Web/API/Window.open
当t1.html通过
showModalDialog
打开t1.html(即自己)的时候,returnValue
竟起作用了,但在子窗口打开的情况下父窗口仍然可以操作,不同的是的showModalDialog
后面的语句在关闭子窗口后执行了,说明此时没有1中的那个错误了;但如果子页面刷新了,则无论之后给
returnValue
赋什么值,最终showModalDialog
的返回值将一直是子页面第一次刷新前给returnValue
所赋的值,如果第一次刷新前没有给returnValue
赋值,则将是undefined
,这说明子页面在刷新后与父页面失去了联系,导致returnValue
失效;在子窗口打开情况下,虽然父窗口能够操作,但在父窗口中点击“点击刷新”后两个
alert
都执行了,而页面却没有刷新,说明有些特殊操作如window.location.reload();
将会等到子窗口关闭后才会执行。
通过测试1得知在chrome下本地直接浏览网页的形式使用showModalDialog
存在类似跨域访问的错误,因此需要将网页放到Web应用服务器上测试,至于子页面刷新导致的问题也许就那样了,算是个bug吧。
测试2
将三个页面放到Web应用服务器(Tomcat)上,然后打开t1.html浏览进行测试。
测试结果:
- IE、Firefox没有问题;
- Chrome下则
returnValue
基本有效,具体细节:- 正常操作情况下,能够通过
returnValue
返回数据,showModalDialog
后面的代码也能在关闭子窗口后执行; - 但如果子页面刷新了,则无论之后给
returnValue
赋什么值,最终showModalDialog
的返回值将一直是子页面第一次刷新前给returnValue
所赋的值,如果第一次刷新前没有给returnValue
赋值,则将是undefined
,这说明子页面在刷新后与父页面失去了联系,导致returnValue
失效; - 在子窗口打开情况下,虽然父窗口能够操作,但在父窗口中点击“点击刷新”后两个
alert
都执行了,而页面却没有刷新,说明有些特殊操作如window.location.reload();
将会等到子窗口关闭后才会执行。
- 正常操作情况下,能够通过
总结
鉴于网上发表的关于Chrome之returnValue
的文章都是几年前的,也许那时确实是完全不支持returnValue
吧,不过我拿了个较老的版本(v11)测过,结果大致跟新版一样。
但Chrome虽然支持returnValue
,但使用体验却不怎么样,有以下几点:
- 打开子窗口情况下,还是能够操作父窗口;
- 子窗口在刷新后,
returnValue
就失效了(window.dialogArguments
也变为undefined
了),只能返回第一次刷新前的returnValue(该问题可通
;window.opener
传参解决,该属性指向父窗口,且不会因为刷新导致失效,具体请参考ref1文中的“解决returnValue问题”小节)
于是乎可以说Chrome不支持returnValue
吧,在之后的版本中showModalDialog
这个方法应该会被移除了,所以说这个没有什么意义了啊。
如果一定要继续用showModalDialog
的话,可以考虑在子窗口中通过window.opener
与父窗口进行传参来代替returnValue
的方式,而用open
来代替showModalDialog
,而在子窗口打开情况下,可以在父窗口中覆盖一层div来禁用用户操作等等,还是可以将就着模拟showModalDialog
的效果的,但要完全模拟,有点困难啊。
参考资料
returnValue of Chrome的更多相关文章
- chrome中showModalDialog解决方案
调用myShowModalDialog function myShowModalDialog(url, width, height, callback) { if(window.showModalDi ...
- onbeforeunload事件兼容性操作
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...
- Chrome不支持showModalDialog模态对话框和无法返回returnValue的问题
父窗体部分js代码: var returnValue = window.showModalDialog("son.html ", window); //for chrome if ...
- 【转载】showModalDialog returnValue is undefined in Google Chrome
showModalDialog returnValue is undefined in Google Chrome Posted on August 22, 2012by briancaos For ...
- JavaScript自定义浏览器滚动条兼容IE、 火狐和chrome
今天为大家分享一下我自己制作的浏览器滚动条,我们知道用css来自定义滚动条也是挺好的方式,css虽然能够改变chrome浏览器的滚动条样式可以自定义,css也能够改变IE浏览器滚动条的颜色.但是css ...
- [No000080]右键解锁增强Chrome插件开发,破除防复制
昨天用360极速(虽然我不喜欢360.)浏览器,登陆知乎查阅一些东西,突然感觉有些观点很赞同,想copy转载一下,我了个去,它丫的居然不让我复制. 地址:https://www.zhihu.com/q ...
- Javascript操作剪切板数据(支持IE、Chrome、360、搜狗),亲测!
clipboarddata只能在IE浏览器中使用,在chrome下会提示对象未定义!以下的方法支持IE.Chrome.360.搜狗等浏览器,其它浏览器还未验证. <!DOCTYPE html&g ...
- js添加事件、移除事件、阻止冒泡、阻止浏览器默认行为等写法(兼容IE/FF/CHROME)
转自:http://blog.csdn.net/itchiang/article/details/7769341 添加事件 var addEvent = function( obj, type, ...
- 从Chrome源码看JS Array的实现
.aligncenter { clear: both; display: block; margin-left: auto; margin-right: auto } .crayon-line spa ...
随机推荐
- 三星手机root后开启调试模式
背景说明:三星手机高版本的手机进行root后也无法安装xposed,无法开启debuggable,使用androistdio无法进行调试. 1 .连接ddms无法显示正在运行的进程. 2.安装mpro ...
- 【Silverlight】Bing Maps学习系列(四):使用图钉层(Pushpin layer)及地图图层(MapLayer)(转)
[Silverlight]Bing Maps学习系列(四):使用图钉层(Pushpin layer)及地图图层(MapLayer) 如果我们需要在Bing Maps中加入一个小图钉标记,该如何实现了? ...
- mysql与mongoDB的特点和优劣
首先分析下mysql与mongoDB的特点和优劣 从图中分析: 再来分析下应用场景: a.如果需要将mongodb作为后端db来代替mysql使用,即这里mysql与mongodb 属于平行级别,那么 ...
- IDEA中项目src目录下无法创建java文件的问题
出现的问题如下,是因为该目录不是源码目录 解决办法 设置成功
- Tomcat优化和JVM分析工具
Tomcat的常见优化和JVM常见分析工具 Tomcat的常用优化配置 (1) 内存空间: /etc/sysconfig/tomcat JAVA_OPTS="-server -Xms32g ...
- 洛谷 P2365 任务安排【dp】
其实是可以斜率优化的但是没啥必要 设st为花费时间的前缀和,sf为Fi的前缀和,f[i]为分组到i的最小花费 然后枚举j转移,考虑每次转移都是把j到i分为一组这样意味着j及之后的都要增加s的时间,同时 ...
- Net 发布网站中遇到的几点问题
1.windows 身份验证设置 打开IIS==>=>找到网站==> 身份验证==>打开功能==>启用windows身份验证 网站设置: 博客参考: http://blo ...
- Androidstudio的安装与使用调试
1安装与基本使用 1.1androidstudio的安装 1.到android-studio\bin文件夹里面,根据自己的电脑配置,打开studio.exe或者studio64.exe 2.按照向导默 ...
- C#命名空间 using的用法
using的用法: 1. using指令:引入命名空间 这是最常见的用法,例如: using System; using Namespace1.SubNameSpace; 2. using stati ...
- PS如何批量整理图片大下
https://jingyan.baidu.com/article/cdddd41cc7849853cb00e193.html