背景使用 window.open 进行弹窗显示,实现微信二维码弹窗功能在双屏情况下,chrome浏览器位于副屏弹窗时,会存在弹窗位置异常问题。目前网上相关解析及解决方案几乎没有,故写此文章以作分享。文章重点双屏情况下,chrome浏览器弹窗位置问题多屏幕时,chrome浏览器位于非主屏进行弹窗显示时,设置弹窗的left,top将会异常本文将分析其显示异常的原因,并给出解决方案解决该问题的分析过程这是本文分享的另一个重点除了解决方案,希望能通过本文和大家分享笔者解决该问题时的思路和方法。这些方法可能不是最优的,但希望能给大家带来一点触动或者启示。在解决到其他问题的时候也用得上。window.open的第三个参数及其兼容性介绍window.open方法相信大家都不会陌生,通常用于传递一个地址参数,新建一个浏览器tab页面。但除了第一个地址参数,window.open还另外接收两个参数,分别是「strWindowName(新窗口的名称)」,「strWindowFeatures(新窗口特性)」这强调的是第三个参数,当设置了第三个参数后,新开的弹窗将会在原页面的基础上,已非tab页面的形式进行显示,有以下几个特点在原页面上进行弹窗显示,而不是新起浏览器tab页面进行跳转。其显示方式类似alert弹窗,属于原页面的一个功能模块,而不是跳转至新页面。非tab页面,这意味着它不像其他tab页面那样可以放在浏览器tab栏中,它是折叠不进去了,是以弹窗的形式呈现。第三个参数「strWindowFeatures」可以设置新窗口特性,例如宽度,高度,距顶,距左,是否显示滚动条等等。本文不做详细介绍,参数详情可以参考这篇文章需要注意的是,strWindowFeatures里的特效并不是每个浏览器都支持的,不同于「dom」,这属于「bom(borwser Object Model)」的内容。具体兼容性这里也不讲了,网上也有相关文章chrome的兼容性与坑(重点一)异常的显示即使看完上面的兼容性文章,当你使用chrome浏览器,位于非主屏进行弹窗时,依然会存在位置设置异常的问题。实现居中显示弹窗,一般代码会这样写const windowWidth = window.screen.width // 屏幕宽度const windowHeight = window.screen.height // 屏幕高度const pageWidth = 600 // 弹出窗口的宽度const pageHeight = 550 // 弹出窗口的高度let pageTop = (windowHeight - pageHeight) / 2 // 窗口的垂直位置let pageLeft = (windowWidth - pageWidth) / 2 // 窗口的水平位置;window.open(‘xxx’, ‘xxx’, width=${pageWidth},height=${pageHeight},top=${pageTop},left=${pageLeft}) // 实现居中弹窗这段代码在主屏幕显示没有问题,可以居中显示,但如果将页面移换到副屏幕进行弹窗时。你会发现,无论参数怎么设置,弹窗都会在屏幕最左侧或屏幕最右侧进行显示,并不是水平居中。点击这里查看示例异常的原因及其解决方案原因可能很多同学都难以想到,这是因为弹窗的left和top参数,并不是基于当前页面作为原点进行计算的,而是以主屏幕作为原点进行计算所以进行位置设置时,需要计算其基于主屏幕的偏移值。那怎么知道当前是否处于主屏幕上呢?可以通过window.screen.availLeft参数来解决,该参数返回浏览器可用空间左边距离屏幕(系统桌面)左边界的距离。通过该参数,甚至不需要知道目前处于哪个屏幕上,直接加上该参数即可基于当前屏幕进行定位。修改后的代码如下const { availLeft, // 返回浏览器可用空间左边距离屏幕(系统桌面)左边界的距离。 availHeight, // 浏览器在显示屏上的可用高度,即当前屏幕高度 availWidth, // 浏览器在显示屏上的可用宽度,即当前屏幕宽度} = window.screenconst pageWidth = 600 // 弹出窗口的宽度const pageHeight = 550 // 弹出窗口的高度let pageTop = (availHeight - pageHeight) / 2 // 窗口的垂直位置let pageLeft = (availWidth - pageWidth) / 2 // 窗口的水平位置;left += availLeft // 加上屏幕偏移值window.open(‘xxx’, ‘xxx’, width=${pageWidth},height=${pageHeight},top=${pageTop},left=${pageLeft}) // 实现居中弹窗「top」参数的设置同样存在这个问题如果主屏幕和副屏幕并不是处于相同的高度,「top」值的设置同样会由于距系统主屏幕定位,而发生定位异常的显示。看下面这张图可能更好地理解另外目前笔者发现,这个兼容性问题,仅会在chrome内核的浏览器存在,safari上运行是不存在该问题的。综上所述,得出最终的解决方案为const { availTop, // 返回浏览器可用空间左边距离屏幕(系统桌面)左边界的距离。 availLeft, // 返回浏览器可用空间左边距离屏幕(系统桌面)左边界的距离。 availHeight, // 浏览器在显示屏上的可用高度,即当前屏幕高度 availWidth, // 浏览器在显示屏上的可用宽度,即当前屏幕宽度} = window.screenconst pageWidth = 600 // 弹出窗口的宽度const pageHeight = 550 // 弹出窗口的高度let pageTop = (availHeight - pageHeight) / 2 // 窗口的垂直位置let pageLeft = (availWidth - pageWidth) / 2 // 窗口的水平位置;if (navigator.userAgent.indexOf(‘Chrome’) !== -1) { // 兼容chrome的bug top += availTop // 距顶偏移值 left += availLeft // 距左偏移值}window.open(‘xxx’, ‘xxx’, width=${pageWidth},height=${pageHeight},top=${pageTop},left=${pageLeft}) // 实现居中弹窗问题解决过程(重点二)笔者遇到该问题是通过如下方式一一寻找解决方案百度最基础,成本最低的一步,笔者进行过以下关键字的搜索(这里主要突出关键字提取)window.open 居中显示window.open left chromewindow.open left 异常window.open 定位 异常window.open chrome 兼容性window.open 双屏显示异常搜索结果,找到了相关的问题,但未能找到真正有效的解决方案。问答论坛stackoverflow,国外著名的编程问答网站,纯英文,内容全。segmentfault,国内的stackoverflow,内容也不错。MDN官网维基百科:MDN Web Docs(旧称Mozilla Developer Network、Mozilla Developer Center,简称MDN)是一个汇集众多Mozilla基金会产品和网络技术开发文档的免费网站。一般可以看作前端基础函数的官方说明文档,具有一定的权威性,当然一定程度上会更为难懂其他页面代码分析寻找网上实现了该功能的网站,下载其页面代码进行分析。网上的代码都是加密过的,虽然不直观,但能推测或猜出一些端倪各关键词搜索首先,通过chrome调试工具,找到触发弹窗的按钮ctrl+s,下载整个页面,通过IDE全局搜索整个页面中关于该按钮的信息,如class,id,及其他属性值,能定位到该按钮的属性都全局搜索一遍逐文件查看,有无相关配置window.open 函数名搜索打开弹窗肯定需要通过该语句,全局搜索,如果window没被覆盖的话应该能找到第三个参数搜索根据 strWindowFeatures 可配置项目进行全局搜索,提取其特点,如「scrollbars」,「titlebar」这些变量以及其字符串形式传参的特点,搜索「,left=」「,height=」重置函数终极大招,函数重置,及通过在chrome控制台重置该函数,来观察其传参情况打开chrome控制台,找到Console栏,拷贝如下代码window.open = function () { console.log(arguments)}再此进行登录弹窗操作,触发函数执行笔者是在前三个方法都失败的情况下,通过第四个方法找到的问题所在。发现其left值传参为负数,在自己项目中设置为负数也能实现居中效果从而推测出原因感谢阅读,祝好
...