高版本Chrome兼容window.showModalDialog办法

方式一:回调

兼容方式:
由于showmodaldialog 不属于W3C标准,在新版本浏览器中不再受支持,我们需要使用window.open等方法自定义一个showmodaldialog 代替。
兼容效果:
不和当前使用的前端框架冲突的情况下无需对被打开的模态框子页面做任何修改。
打开模态框的主页面可能需要修改传入参数(如果格式统一可以在showmodaldialog写死,从而不修改参数)。

下面直接上代码,复制即可测试。

将要打开模态框的主页面papa.html代码:

<!DOCTYPE html>
<html lang="zh"><head><title>主页面</title><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><meta charset="utf-8"></head><body><input id="a"/><button onclick="callSon()">打开模态框</button/><fieldset><legend>子页面返回</legend><span id="content"></span></fieldset><script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.js"></script><Script type="text/javascript" src="papa.js"></script ></body>
</html>

将要打开模态框的主页面papa.js代码:

//定义一个全局变量判定是否原生支持showModalDialog方法
var has_showModalDialog = !!window.showModalDialog;
//当其不受支持时自定义window.showModalDialog
if(!has_showModalDialog){/* url传入被打开网页的地址* dialogArguments传入子页面需要的参数和判断参数:*     windowName4Open传入被打开网页的名称;*     callback4Open传入子窗口返回returnValue时的回调;*   autoCallback4Open用于打开的网页判断callback4Open是否存在* features子网页的样式*/window.showModalDialog = function(url,dialogArguments,features){//新窗口的名字。如果该名字的窗口已经存在,则再次调用时占用该窗口,不再新建窗口。如果省略,(浏览器会)默认_blankvar name = dialogArguments.windowName4Open || '_blank';if(name=='_blank' && window.hasOpenWindow){//当窗口名为_blank时,再次调用不会占用未关闭的_blank子窗,需要手动避免弹出多个窗口window.myNewWindow.focus();return;}//因window.showmodaldialog 与 window.open 参数不一样,所以封装的时候用正则去格式化一下参数if(features)features = "modal=yes,"+features.replace(/(dialog)|(px)/ig,"").replace(/;/g,',').replace(/\:/g,"=");var left = (window.screen.width - parseInt(features.match(/width[\s]*=[\s]*([\d]+)/i)[1]))>>1;var top = (window.screen.height - parseInt(features.match(/height[\s]*=[\s]*([\d]+)/i)[1]))>>1;features+=',left='+left+',top='+top;//窗口居中//打开子页面window.myNewWindow = window.open(url,name,features);//定义自动返回returnValueif("function" === typeof dialogArguments.callback4Open /*其他条件*/){//如果不冲突的情况下通过劫持子窗returnValue,达到无需在子窗手动执行回调的目的dialogArguments.autoCallback4Open=true;Object.defineProperty(myNewWindow, 'returnValue', {get: function() {//不需要写成window.myNewWindow.returnValue就可以return returnValue;},set: function(value) {returnValue = value;//执行函数dialogArguments.callback4Open(value);}});}else{Object.defineProperty(myNewWindow, 'returnValue', {});}window.hasOpenWindow = true;if(dialogArguments){//open()不支持传递参数,通过这种方式向子页面传递参数,因为打开页面速度远远慢于本方法执行速度,因而子页面总能获得传递的参数,//也可在子窗load事件发生后使用myNewWindow.postMessage(dialogArguments,url),但在子窗还未load时监听可能无效,但它可以突破同源限制window.myNewWindow.dialogArguments=dialogArguments;}  //window.myNewWindow.moveTo(left,top);}
}
//打开模态框
function callSon(){url = 'son.html';var sonStyle="dialogWidth:500px;dialogHeight:450px;help:no;resizable:no;center:yes;scroll:yes;status:no";var param={val:document.getElementById("a").value?document.getElementById("a").value:"son"}//固定情况下这两个可以写死在showModalDialog,如果不想多次点击打开多个子页面,则不要给子页面命名param.windowName4Open='son';param.callback4Open=callSonChrome;var val = window.showModalDialog(url,param,sonStyle);//chrome下返回不执行afterCall,而是作为回调(callSonChrome),因为IE下showModalDialog是阻塞的可以直接afterCall,open则是异步的;if(!has_showModalDialog)return; afterCall(val);
}
//为打开的子窗口定义方法,让打开的窗口关闭时通过window.opener赋值回来并执行
function callSonChrome(val){afterCall(val);
}
//获得模态框返回值后执行的业务方法
function afterCall(val){$("#content").html(val);
}

被打开的模态框子页面son.html代码:

<!DOCTYPE html>
<html lang="zh"><head><title>子页面</title><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><meta charset="utf-8"></head><body><input id="a"/><button onclick="closeToRetuen()">关闭模态框并返回</button><script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.js"></script><Script type="text/javascript" src="son.js"></script ></body>
</html>

被打开的模态框子页面son.js代码:

window.addEventListener('message', function (e) {//监听父窗postMessage发送的消息console.log(e.data);
},false);
var param  = window.dialogArguments;
document.getElementById("a").value=param.val;
function closeToRetuen() {var a = $("#a").val();//chrome环境未劫持returnValue情况if (window.opener != undefined && param.callback4Open && !param.autoCallback4Open ) { //关闭前调用父窗口方法返回需要返回的对象或字符串param.callback4Open(a); }  //ie环境和chrome环境劫持returnValue情况else {  window.returnValue = a;}window.close();
}
//_blank情况下页面关闭时主动通知调用页面我将关闭
window.onbeforeunload=function(){window.opener.hasOpenWindow=false;
}

测试:
测试浏览器Google Chrome 版本 69.0.3497.100(正式版本) (64 位)
打开模态框

关闭模态框

参考文章:

https://blog.csdn.net/ts472960087/article/details/45843257

方式二:postMessage

兼容方式
较新的浏览器现在基本上都支持window.postMessage方法,我们可以通过他来进行不同页面之间的跨域通信(注意!这有跨域安全问题!)
兼容效果
代码改动量较少,子页面执行postMessage,主页面仅需添加监听即可,但需要较高的浏览器版本,不同浏览器之间有细微差异(基本功能不影响)
语法

otherWindow.postMessage(message, targetOrigin, [transfer]);/*otherWindow
其他窗口的一个引用,
比如iframe的contentWindow属性、
执行window.open返回的窗口对象、
或者是命名过或数值索引的window.frames。message
将要发送到其他 window的数据。
它将会被结构化克隆算法序列化。
这意味着你可以不受什么限制的将数据对象安全的传送给目标窗口而无需自己序列化。targetOrigin
通过窗口的origin属性来指定哪些窗口能接收到消息事件,
其值可以是字符串"*"(表示无限制)或者一个URI。
在发送消息的时候,
如果目标窗口的协议、主机地址或端口这三者的任意一项不匹配targetOrigin提供的值,那么消息就不会被发送;
只有三者完全匹配,消息才会被发送。
这个机制用来控制消息可以发送到哪些窗口;例如,当用postMessage传送密码时,这个参数就显得尤为重要,
必须保证它的值与这条包含密码的信息的预期接受者的origin属性完全一致,来防止密码被恶意的第三方截获。
如果你明确的知道消息应该发送到哪个窗口,那么请始终提供一个有确切值的targetOrigin,而不是*。
不提供确切的目标将导致数据泄露到任何对数据感兴趣的恶意站点。transfer (可选)
是一串和message 同时传递的 Transferable 对象.这些对象的所有权将被转移给消息的接收方,而发送一方将不再保有所有权。
*///简单示例
window.addEventListener("message", receiveMessage, false);function receiveMessage(event)
{// For Chrome, the origin property is in the event.originalEvent// object. // 这里不准确,chrome没有这个属性// var origin = event.origin || event.originalEvent.origin; var origin = event.originif (origin !== "http://example.org:8080")return;// ...
}
/*message 的属性有:data
从其他 window 中传递过来的对象。
origin
调用 postMessage  时消息发送方窗口的 origin . 这个字符串由 协议、“://“、域名、“ : 端口号”拼接而成。
例如 “https://example.org (隐含端口 443)”、“http://example.net (隐含端口 80)”、“http://example.com:8080”。
请注意,这个origin不能保证是该窗口的当前或未来origin,因为postMessage被调用后可能被导航到不同的位置。
source
对发送消息的窗口对象的引用; 您可以使用此来在具有不同origin的两个窗口之间建立双向通信。
/*

下面直接上代码.
将要打开模态框的主页面js代码:

/** A窗口的域名是<http://example.com:8080>,以下是A窗口的script标签下的代码:*/var popup = window.open(...popup details...);// 如果弹出框没有被阻止且加载完成// 这行语句没有发送信息出去,即使假设当前页面没有改变location(因为targetOrigin设置不对)
popup.postMessage("The user is 'bob' and the password is 'secret'","https://secure.example.net");// 假设当前页面没有改变location,这条语句会成功添加message到发送队列中去(targetOrigin设置对了)
popup.postMessage("hello there!", "http://example.org");function receiveMessage(event)
{// 我们能相信信息的发送者吗?  (也许这个发送者和我们最初打开的不是同一个页面).if (event.origin !== "http://example.org")return;// event.source 是我们通过window.open打开的弹出页面 popup// event.data 是 popup发送给当前页面的消息 "hi there yourself!  the secret response is: rheeeeet!"
}
window.addEventListener("message", receiveMessage, false);

被打开的模态框子页面js代码:

/** 弹出页 popup 域名是<http://example.org>,以下是script标签中的代码:*///当A页面postMessage被调用后,这个function被addEventListener调用
function receiveMessage(event)
{// 我们能信任信息来源吗?if (event.origin !== "http://example.com:8080")return;// event.source 就当前弹出页的来源页面// event.data 是 "hello there!"// 假设你已经验证了所受到信息的origin (任何时候你都应该这样做), 一个很方便的方式就是把event.source// 作为回信的对象,并且把event.origin作为targetOriginevent.source.postMessage("hi there yourself!  the secret response " +"is: rheeeeet!",event.origin);
}window.addEventListener("message", receiveMessage, false);

参考文章:

https://developer.mozilla.org/zh-CN/docs/Web/API/Window/postMessage

高版本Chrome兼容window.showModalDialog办法相关推荐

  1. 高版本Chrome网页直接播放海康威视大华RTSP流方案,不需服务器转码转流,支持H.265、H.264及2K/4K高清视频

    近期公司在做一个智慧城市项目,需要在高版本Chrome网页播放海康威视.大华.或者华为摄像头RTSP流,于是在网上开始找对应的解决方案,没想到网上各种转码转流方案纷繁复杂,找到一款稳定商用满足需求的很 ...

  2. 在高版本chrome播放摄像头实时RTSP视频流,并抓图、录像、回放、倍速等

    近期研究在VUE中播放RTSP实时视频,客户要求延迟低于300毫秒,并且要求支持多路同时播放,支持H.265格式视频,比较了下目前市场上常见的几种方案,以供大家参考! 一.海康威视官方WEB解决方案: ...

  3. 如何在高版本Chrome中播放RTSP实时视频?

    背景 随着互联网基础设施的完善以及4G.5G等技术的大规模商用,在Chrome.Firefox.Edge等浏览器播放RTSP视频流也慢慢成为了信息化系统的行业标准. 早些年还可用VLC播放器在网页中播 ...

  4. Eclipse高版本无法兼容FatJar的问题解决

    发现eclipse打包jar无法连带打包第三方lib,于是选择安装插件fatjar,现在说明fatjar安装过程: 1.安装方法:    1)下载安装:    https://sourceforge. ...

  5. html禁止浏览器修改字号,在高版本Chrome浏览器中自定义强制样式表修改页面字体显示...

    Firefox有一个比较好的功能,就是禁用页面指定的字体,改为使用用户强制指定的字体来渲染也页面.但是在Chrome中却没有这样的设置,Chrome的原意是尊重网页设计者的意图,尽可能原样显示页面.但 ...

  6. 高版本Chrome浏览器多路(25路)同时播放海康威视、大华摄像头RTSP流视频流方案

    猿大师VLC播放程序在Chrome同时播放25路RTSP摄像头视频流效果,CPU及内存占用情况

  7. 91版本Chrome跨域解决办法

    windows: 1.在右击Chrome/Edge的快捷方式, 点击"属性". 2.在"目标(T)"属性中末尾加上 –disable-features=Same ...

  8. 如何在高版本谷歌Chrome浏览器中用VLC播放海康、大华RTSP实时视频?

    一.背景 随着互联网基础设施的完善以及4G.5G等技术的大规模商用,在Chrome.Firefox.Edge等浏览器播放RTSP视频流也慢慢成为了信息化系统的行业标准. 早些年还可用VLC播放器在网页 ...

  9. 【转载】Chrome插件在高版本浏览器中安装报错解决

    为什么80%的码农都做不了架构师?>>>    Chrome插件在高版本浏览器中安装报错解决技术 maybe yes 发表于2014-12-17 17:20 原文链接 : http: ...

最新文章

  1. 机器人会模仿人类微笑了,但我总觉得这笑容……
  2. saltstack管理saltstack认证相关
  3. 细说JVM的数据类型、堆与栈
  4. python 哪些比赛项目_70个超火python小项目列表,拿走·不谢
  5. 基于Struts2的供求信息网设计(一)
  6. webpack --- 在项目中使用React
  7. leetcode 1818. 绝对差值和
  8. python求50的阶乘_python中求阶乘
  9. 狐假虎威的故事,狐假虎威的故事告诉我们什么道理?
  10. java 新增的方法外部调用提示不存在_Java面试简答题(一)
  11. 拓端tecdat|基于keras平台CNN神经网络模型的服装识别分析
  12. python 任务计划_python任务计划
  13. 常规波束形成法matlab仿真,常规波束形成matlab程序
  14. Cortex-M3 (NXP LPC1788)之外部中断操作
  15. linux系统 安装主板驱动,I810 Graphics LINUX Driver的安装
  16. 一战北邮计专考研经验分享
  17. 个人收藏的一些资源网站
  18. python爬虫20 | 小帅b教你如何使用python识别图片验证码
  19. P-Link ARM Cortex-M脱机编程器开源前的一些准备工作----第四章 几个重要的结构体介绍
  20. 终于有人把 Docker 讲清楚了,别再说不会 Docker 了!

热门文章

  1. mysql端口查看与修改-netstat命令使用
  2. Dense Deep Unfolding Network with 3D-CNN Prior for Snapshot Compressive Imaging
  3. CentOS 8 安装golang
  4. windows下boost的安装与初试
  5. 项目管理中,项目干系人的角色和责任
  6. 【模拟】图书馆书目检索
  7. 机器人图形变变变_幼儿园大班数学《图形变变变》教案
  8. PPT设计思维干货分享(二)
  9. 嵌入式课程设计总结(十)
  10. 分页第一页用0还是1_码动未来,用0和1改变世界