今年十月份,我曾发布一篇文章《Chrome53 最新版惊现无厘头卡死 BUG!》,不过那个BUG在最新的 Chrome 54 中已经修正。html
而今天即将发布的Chrome弱智BUG:chrome
最近在和客户沟通中,发现一个奇怪问题:浏览器
1. 页面中存在一个选项卡控件,选项卡里面是IFrame,页面初始显示时有纵向滚动条出现安全
2. 来回切换选项卡一次,原来选项卡页面的滚动条竟然消失了!!网络
3. 奇怪的时,此时在选项卡页面内滑动鼠标滚轮,仍是可以上下滚动页面的app
页面打开时的样子:工具
来回切换一次选项卡后的样子:开发工具
奇怪的是,此时鼠标滚动还能上下滚动页面:测试
固然首先怀疑的就是本身写的代码问题,可是查了一遍竟然毫无头绪。在此期间咱们还发现以下问题:优化
1. FineUIPro从最新版v3.3,到以前v3.2,v3.1,v3.0.... 无一例外都有这个问题。这就有点难以想象了,咱们开源版有 1300 多位捐赠用户,专业版有 100 多个企业客户,如此明显的一个BUG不可能这么多版本都没有被发现!!
假设以前的版本根本就没有这个问题,那么就是浏览器版本升级引入的BUG了。
2. 在Firefox,Edge,IE11,IE10,IE9,IE8下测试都没有这个问题,只有Chrome下才出现问题!!
因为,咱们不得不怀疑是新版 Chrome 引入的BUG,为了验证这个想法,咱们须要一个很是简单的可重现例子。
因为FineUIPro自己的客户端代码仍是很复杂了,为了不其余代码的影响,咱们须要一个可重现的简单的例子:
页面一:
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title> </title> </head> <body> <input type="button" value="页面二" onclick="document.getElementById('frame1').style.display = 'block'; document.getElementById('frame2').style.display = 'none';" /> <input type="button" value="页面三" onclick="document.getElementById('frame1').style.display = 'none'; document.getElementById('frame2').style.display = 'block';" /> <div style="border:solid 1px red;width:400px;height:200px;"> <iframe id="frame1" style="width:100%;height:100%;border:none;" src="./page2.html"></iframe> <iframe id="frame2" style="width:100%;height:100%;border:none;display:none;" src="./page3.html"></iframe> </div> </body> </html>
这个页面代码很是简单,两个按钮,两个IFrame,默认显示第一个IFrame,经过按钮来切换两个IFrame的显示。
页面二:
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title> </title> </head> <body> page2 </body> </html>
页面三:
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title> </title> </head> <body> page3 <br /><br /><br /><br /><br /><br /><br /><br /><br /><br /> <br /><br /><br /><br /><br /><br /><br /><br /><br /><br /> <br /><br /><br /><br /><br /><br /><br /><br /><br /><br /> <br /><br /><br /><br /><br /><br /><br /><br /><br /><br /> page3 </body> </html>
下面分别在不一样浏览器下运行效果:
Chrome 55.0.2883.75
FireFox 50.0.2
Edge
IE11
毫无疑问,这个是Chrome的BUG,那么究竟是从哪一个版本开始才出现的呢,这个就很差追踪。
咱们也没有那么多精力把每一个Chrome版本都测试下,因此就安装了两款国内的双核浏览器,分别用Chrome内核测试:
第一款产品是 360安全浏览器,极速模式下 Chrome 版本是 45,比较老,正好用来测试:
哈哈,看来 Chrome v45 尚未这个BUG,这就好办,说明这个BUG是Chrome新版才引入的!!
第二款产品是 QQ 浏览器,Chrome内核是 53
看来 Chrome 53 版本已经引入了这个BUG。
因此咱们能够大体把引入这个BUG的Chrome版本限定在 v53 - v55(这个是2016-12-05 才发布的)。
既然那么多Chrome版本都存在这个问题,要么是Google开发人员没发现,要么是不想修正了。
这里也顺便吐槽一下Chrome:虽然Chrome的运行速度最快,开发工具也很是方便,可是长期坚持在JavaScript编码第一线,竟然发现了好多个仅在Chrome下出现的问题,让人恍惚有点IE6的感受。仅仅是在 FineUIPro 就有好几处是 Chrome Only 的代码,有空我会再分享几个出来。
无论Google怎么办,这个问题仍是要解决,又要是 Chrome Only 的代码了,哎!
1. 首先怀疑是 iframe 的 width:100% 和 height:100% 搞的鬼
因为代码结构太简单,没有多少让人怀疑的地方,就先把这个宽度和高度改成固定值试下:
页面四:
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title> </title> </head> <body> <input type="button" value="页面二" onclick="document.getElementById('frame1').style.display = 'block'; document.getElementById('frame2').style.display = 'none';" /> <input type="button" value="页面三" onclick="document.getElementById('frame1').style.display = 'none'; document.getElementById('frame2').style.display = 'block';" /> <div style="border:solid 1px red;width:400px;height:200px;"> <iframe id="frame1" style="width:400px;height:200px;border:none;" src="./page2.html"></iframe> <iframe id="frame2" style="width:400px;height:200px;border:none;display:none;" src="./page3.html"></iframe> </div> </body> </html>
运行一下,问题依旧!
这时若是用Chrome调试工具查看,发现滚动条的位置还在,只是不显示:
2. 以前遇到相似的问题,咱们能够强制浏览器从新渲染
网络上早已有相应的解决版本:查看StackOverflow上相关的技术帖子
页面五:
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title> </title> </head> <body> <script> function fixSize() { var container1 = document.getElementById('container1'); container1.style.overflow = 'hidden'; container1.scrollWidth; container1.style.overflow = 'auto'; } </script> <input type="button" value="页面二" onclick="document.getElementById('frame1').style.display = 'block'; document.getElementById('frame2').style.display = 'none'; fixSize();" /> <input type="button" value="页面三" onclick="document.getElementById('frame1').style.display = 'none'; document.getElementById('frame2').style.display = 'block'; fixSize();" /> <div style="border:solid 1px red;width:400px;height:200px;" id="container1"> <iframe id="frame1" style="width:400px;height:200px;border:none;" src="./page2.html"></iframe> <iframe id="frame2" style="width:400px;height:200px;border:none;display:none;" src="./page3.html"></iframe> </div> </body> </html>
运行,问题依旧!
怪了,这个强制Chrome从新渲染的代码以前验证过的,此次竟然也不行了。
郁闷中。。。。。先出去散步。。。。。。
散步中。。。。
散步中。。。。
散步中。。。。
散步中。。。。
散步中。。。。
散步中。。。。
散步中。。。。
散步中。。。。
散步中。。。。
散步中。。。。
散步中。。。。
散步中。。。。
散步中。。。。
散步中。。。。
散步中。。。。
散步中。。。。
散步中。。。。
散步中。。。。
散步中。。。。
散步中。。。。
3. 散步回来,以为仍是应该从强制Chrome渲染入手,此次咱们来改变高度
页面六:
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title> </title> </head> <body> <script> function fixSize() { var container1 = document.getElementById('container1'); container1.style.height = '199px'; container1.scrollWidth; container1.style.height = '200px'; } </script> <input type="button" value="页面二" onclick="document.getElementById('frame1').style.display = 'block'; document.getElementById('frame2').style.display = 'none'; fixSize();" /> <input type="button" value="页面三" onclick="document.getElementById('frame1').style.display = 'none'; document.getElementById('frame2').style.display = 'block'; fixSize();" /> <div style="border:solid 1px red;width:400px;height:200px;" id="container1"> <iframe id="frame1" style="width:100%;height:100%;border:none;" src="./page2.html"></iframe> <iframe id="frame2" style="width:100%;height:100%;border:none;display:none;" src="./page3.html"></iframe> </div> </body> </html>
帅呆了,此次竟然能够了!!!如今Chrome 55下能正常运行了。
4. 优化一下,能够改变iframe的高度,而不是外部容器的高度,这样就不用硬编码了,代码更通用
页面七:
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title> </title> </head> <body> <script> function fixSize(iframeId) { var iframe = document.getElementById(iframeId); iframe.style.height = '99%'; iframe.scrollWidth; iframe.style.height = '100%'; } </script> <input type="button" value="页面二" onclick="document.getElementById('frame1').style.display = 'block'; document.getElementById('frame2').style.display = 'none'; fixSize('frame1');" /> <input type="button" value="页面三" onclick="document.getElementById('frame1').style.display = 'none'; document.getElementById('frame2').style.display = 'block'; fixSize('frame2');" /> <div style="border:solid 1px red;width:400px;height:200px;" id="container1"> <iframe id="frame1" style="width:100%;height:100%;border:none;" src="./page2.html"></iframe> <iframe id="frame2" style="width:100%;height:100%;border:none;display:none;" src="./page3.html"></iframe> </div> </body> </html>
这样也行,也算是解决了这个Chrome Only的BUG!!
每次给老婆提及这样的稀奇古怪事,老婆都会嘲笑我是代码泥瓦匠,只能从外部修修补补。不过能修补上也算是阿弥陀佛了。
谁让咱一直坚持在代码一线呢。
页面一(原始页面,Chrome下存在BUG):http://fineui.com/demo_pro/chromebug1/page1.html
页面四(仍然有问题):http://fineui.com/demo_pro/chromebug1/page4.html
页面五(仍然有问题):http://fineui.com/demo_pro/chromebug1/page5.html
页面六(修正了Chrome下的问题):http://fineui.com/demo_pro/chromebug1/page6.html
页面七(修正了Chrome下的问题):http://fineui.com/demo_pro/chromebug1/page7.html