说实话,我一看到这个returnValue就有点反感,感觉这个就是IE式的老套的用法,因为项目中有用到就了解了下,以下主要是一些我的理解和发现吧。

PS:returnValuewindow的属性,showModalDialogopenwindow的方法。

returnValue是与showModalDialog搭配使用的,showModalDialog用于打开窗口,与open类似效果,但通过showModalDialog打开窗口时有如下特点:

  1. 打开窗口后,将不能再操作父窗口了(正常情况下,父窗口将获取不到焦点了);
  2. 确切的说父窗口在执行showModalDialog这一步时停止了,等待子窗口操作返回,而showModalDialog之后的js代码也就暂时不会执行了;
  3. 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几乎无效,具体细节:

    1. 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

    2. 当t1.html通过showModalDialog打开t1.html(即自己)的时候,returnValue竟起作用了,但在子窗口打开的情况下父窗口仍然可以操作,不同的是的showModalDialog后面的语句在关闭子窗口后执行了,说明此时没有1中的那个错误了;

    3. 但如果子页面刷新了,则无论之后给returnValue赋什么值,最终showModalDialog的返回值将一直是子页面第一次刷新前给returnValue所赋的值,如果第一次刷新前没有给returnValue赋值,则将是undefined,这说明子页面在刷新后与父页面失去了联系,导致returnValue失效;

    4. 在子窗口打开情况下,虽然父窗口能够操作,但在父窗口中点击“点击刷新”后两个alert都执行了,而页面却没有刷新,说明有些特殊操作如window.location.reload();将会等到子窗口关闭后才会执行。

通过测试1得知在chrome下本地直接浏览网页的形式使用showModalDialog存在类似跨域访问的错误,因此需要将网页放到Web应用服务器上测试,至于子页面刷新导致的问题也许就那样了,算是个bug吧。

测试2

将三个页面放到Web应用服务器(Tomcat)上,然后打开t1.html浏览进行测试。

测试结果:
  • IE、Firefox没有问题;
  • Chrome下则returnValue基本有效,具体细节:
    1. 正常操作情况下,能够通过returnValue返回数据,showModalDialog后面的代码也能在关闭子窗口后执行;
    2. 但如果子页面刷新了,则无论之后给returnValue赋什么值,最终showModalDialog的返回值将一直是子页面第一次刷新前给returnValue所赋的值,如果第一次刷新前没有给returnValue赋值,则将是undefined,这说明子页面在刷新后与父页面失去了联系,导致returnValue失效;
    3. 在子窗口打开情况下,虽然父窗口能够操作,但在父窗口中点击“点击刷新”后两个alert都执行了,而页面却没有刷新,说明有些特殊操作如window.location.reload();将会等到子窗口关闭后才会执行。

总结

鉴于网上发表的关于Chrome之returnValue的文章都是几年前的,也许那时确实是完全不支持returnValue吧,不过我拿了个较老的版本(v11)测过,结果大致跟新版一样。

但Chrome虽然支持returnValue,但使用体验却不怎么样,有以下几点:

  1. 打开子窗口情况下,还是能够操作父窗口;
  2. 子窗口在刷新后,returnValue就失效了(window.dialogArguments也变为undefined了),只能返回第一次刷新前的returnValue(该问题可通window.opener传参解决,该属性指向父窗口,且不会因为刷新导致失效,具体请参考ref1文中的“解决returnValue问题”小节)

于是乎可以说Chrome不支持returnValue吧,在之后的版本中showModalDialog这个方法应该会被移除了,所以说这个没有什么意义了啊。

如果一定要继续用showModalDialog的话,可以考虑在子窗口中通过window.opener与父窗口进行传参来代替returnValue的方式,而用open来代替showModalDialog,而在子窗口打开情况下,可以在父窗口中覆盖一层div来禁用用户操作等等,还是可以将就着模拟showModalDialog的效果的,但要完全模拟,有点困难啊。

参考资料

returnValue of Chrome的更多相关文章

  1. chrome中showModalDialog解决方案

    调用myShowModalDialog function myShowModalDialog(url, width, height, callback) { if(window.showModalDi ...

  2. onbeforeunload事件兼容性操作

    <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...

  3. Chrome不支持showModalDialog模态对话框和无法返回returnValue的问题

    父窗体部分js代码: var returnValue = window.showModalDialog("son.html ", window); //for chrome if ...

  4. 【转载】showModalDialog returnValue is undefined in Google Chrome

    showModalDialog returnValue is undefined in Google Chrome Posted on August 22, 2012by briancaos For ...

  5. JavaScript自定义浏览器滚动条兼容IE、 火狐和chrome

    今天为大家分享一下我自己制作的浏览器滚动条,我们知道用css来自定义滚动条也是挺好的方式,css虽然能够改变chrome浏览器的滚动条样式可以自定义,css也能够改变IE浏览器滚动条的颜色.但是css ...

  6. [No000080]右键解锁增强Chrome插件开发,破除防复制

    昨天用360极速(虽然我不喜欢360.)浏览器,登陆知乎查阅一些东西,突然感觉有些观点很赞同,想copy转载一下,我了个去,它丫的居然不让我复制. 地址:https://www.zhihu.com/q ...

  7. Javascript操作剪切板数据(支持IE、Chrome、360、搜狗),亲测!

    clipboarddata只能在IE浏览器中使用,在chrome下会提示对象未定义!以下的方法支持IE.Chrome.360.搜狗等浏览器,其它浏览器还未验证. <!DOCTYPE html&g ...

  8. js添加事件、移除事件、阻止冒泡、阻止浏览器默认行为等写法(兼容IE/FF/CHROME)

    转自:http://blog.csdn.net/itchiang/article/details/7769341 添加事件   var addEvent = function( obj, type, ...

  9. 从Chrome源码看JS Array的实现

    .aligncenter { clear: both; display: block; margin-left: auto; margin-right: auto } .crayon-line spa ...

随机推荐

  1. Android学习笔记-传感器开发之利用传感器和Tween开发简易指南针

    本次我们学习Android传感器的开发,前面已经介绍过了,tween的使用,所以,我们可以结合传感器与tween动画,开发简易的指南针. 首先先介绍一下传感器的相关知识, 在Android应用程序中使 ...

  2. Eclipse离线安装Emmet插件

    Eclipse离线安装Emmet插件 近期发现了一个写前端代码很好的一个东西,一个叫做Emmet的工具,这个工具使用仿CSS选择器的语法来生成代码,大大提高了HTML/CSS代码编写的速度,前身就是大 ...

  3. 2016/2/21 JavaScript简介

    1,javaScript 是什么? 是脚本语言,需要有宿主文件,它的宿主文件是HTML文件.2,它与Java什么关系? 没有什么直接的关系,Java是Sun公司(被Oracle收购了), netspa ...

  4. P2030 遥控车

    P2030 遥控车 2通过 11提交 题目提供者LittleZ 标签二分字符串递推高精洛谷原创 难度尚无评定 提交该题 讨论 题解 记录 最新讨论 暂时没有讨论 题目描述 平平带着韵韵来到了游乐园,看 ...

  5. HTML <iframe> 标签的 src 属性

    HTML <iframe> 标签的 src 属性 <iframe src="/index.html"> <p>Your browser does ...

  6. linux CentOS中创建用户 无密码登录

    首先点击左上角的 “应用程序” -> “系统工具” -> “终端”,首先在终端中输入 su ,按回车,输入 root 密码以 root 用户登录,接着执行命令创建新用户 hadoop: 接 ...

  7. table样式测试总结tr td宽度分析

    题外话:一直以来习惯布局用ul,li样式调整比较方便,不会互相影响出现一些问题,but~现在公司涉及很多表格打印,都是用table写的,好多宽度高度合并啊,组合啊~~~,单元格之间互相影响,有的样式设 ...

  8. linux学习之路6 Vi文本编辑器

    vim是vi的增强版本 vim拥有三种模式: 命令模式(常规模式) vim启动后,默认进入命令模式.任何模式都可以通过按esc键回到命令模式(可以多按几次.命令模式可以通过键入不同的命令完成选择.复制 ...

  9. U - Relatives(欧拉函数)

    Description Given n, a positive integer, how many positive integers less than n are relatively prime ...

  10. ACM_01背包2

    背包4 Time Limit: 2000/1000ms (Java/Others) Problem Description: 有n个重量和价值分别为Wi,Vi的物品,现从这些物品中挑选出总量不超过W的 ...