前言

今年十月份,我曾发布一篇文章《Chrome53 最新版惊现无厘头卡死 BUG!》,不过那个BUG在最新的 Chrome 54 中已经修正。

而今天即将发布的Chrome弱智BUG:

  • 仅 Chrome 53 - Chrome 55(2016-12-05发布的)中存在问题
  • 国内双核浏览器 Chrome 45 中没有问题
  • Firefox,Edge,IE11-IE8浏览器中都没有问题

发现问题

最近在和客户沟通中,发现一个奇怪问题:

1. 页面中存在一个选项卡控件,选项卡里面是IFrame,页面初始显示时有纵向滚动条出现

2. 来回切换选项卡一次,原来选项卡页面的滚动条居然消失了!!

3. 奇怪的时,此时在选项卡页面内滑动鼠标滚轮,还是能够上下滚动页面的

页面打开时的样子:

来回切换一次选项卡后的样子:

奇怪的是,此时鼠标滚动还能上下滚动页面:

当然首先怀疑的就是自己写的代码问题,但是查了一遍居然毫无头绪。在此期间我们还发现如下问题:

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

【原创】Chrome最新版(53-55)再次爆出BUG!的更多相关文章

  1. chrome最新版49跨域问题

    chrome最新版49跨域问题   一.最新版49要用新的参数 加--user-data-dirwindows:"C:\Program Files\Google\Chrome\Applica ...

  2. Facebook再次爆出安全漏洞,9000万用户受影响

    今年上半年开始,美国社交媒体Facebook因数据泄露事件和涉嫌操纵选举等问题频繁接受听证会拷问,然而事情却远没有结束.今年9月Facebook再次爆出安全漏洞,导致9000万用户可能受到影响. 根据 ...

  3. 再次踩bug:遍历删除list(java.util.ConcurrentModificationException)

    再次踩bug:遍历删除list(java.util.ConcurrentModificationException) 使用 List<Long> list = new ArrayList& ...

  4. 【原创】安装LoadRunner12.53 版本时出现Critical error的解决方法

    步骤: 1.在官网上下载LoadRunner12.53正版,只不过要注册,然后官网会给个序列号. 2.安装成功之后,快捷键已创建,打开Virtual User Generator时,提示如下错误: 此 ...

  5. 关于缓存和 Chrome 的“新版刷新”

    在读本文前你要确保读过我的上篇文章<扼杀 304,Cache-Control: immutable>,因为本文是接着上文写的.上文说到,在现代 Web 上,“条件请求/304 响应”绝大多 ...

  6. Chrome V75V76新版无法存为mhtml格式解决办法

    升级到75.76版本后谷歌浏览器Chrome V75.0.3770.142 V76.0.3809.87新版,发现无法另存为/保存网页为MHTML了.原来chrome搞了个"Chrome Fl ...

  7. Chrome最新版如何安装Proxy SwitchyOmega

    由于Chrome的代理设置与windows10的1703及以后的版本不兼容,导致无法使用代理功能,给工作带来了很大的不便.最近发现一款不错的Chrome代理插件Proxy SwitchyOmega,由 ...

  8. [原创]java WEB学习笔记55:Struts2学习之路---详解struts2 中 Action,如何访问web 资源,解耦方式(使用 ActionContext,实现 XxxAware 接口),耦合方式(通过ServletActionContext,通过实现 ServletRequestAware, ServletContextAware 等接口的方式)

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  9. Chrome在新版MacOS上报错 NET::ERR_CERT_WEAK_KEY 解决方法

    现象 原文链接 证书详情: 原因 参考苹果官网给出的提示(https://support.apple.com/en-us/HT210176): RSA秘钥长度必须>=2048,小于这个长度的将不 ...

随机推荐

  1. PyQt4入门学习笔记(四)

    在PyQt4中的事件和信号 事件 所有的GUI应用都是事件驱动的.事件主要是来自于应用的使用者,但是像互联网连接,窗口管理器或者计时器也可以产生事件.当我们调用应用的exec_()方法时,应用就进入了 ...

  2. Oracle 中的操作符

    1.union:对两个结果集进行并集操作,不包括重复行,同时进行默认规则的排序: SELECT * FROM emp WHERE sal < UNION SELECT * FROM emp WH ...

  3. DNS报文格式(RFC1035)

    一.域名和资源记录的定义 1.Name space definitions 2.资源记录定义(RR definitions)      2.1 格式          后面分析报文的时候详细解释.   ...

  4. Redis命令拾遗三(列表List类型)

    本文版权归博客园和作者吴双本人共同所有.转载和爬虫请注明原文地址 Redis五种数据类型之列表类型 Redis五种数据类型之列表类型.你可以存储一个有序的字符串列表一类数据.比如你想展示你所存储的所有 ...

  5. WPF binding 参考

    Introduction This is an article on WPF Binding Cheat Sheet. Some of the Binding won't work for Silve ...

  6. WinForm 对Web Api 增 册 改 查 的基本操作

    WebApi代码: public class ValuesController : ApiController { Entities db=new Entities(); // GET api/val ...

  7. 转载:TypeScript 简介与《TypeScript 中文入门教程》

    简介 TypeScript是一种由微软开发的自由和开源的编程语言.它是JavaScript的一个超集,而且本质上向这个语言添加了可选的静态类型和基于类的面向对象编程.安德斯·海尔斯伯格,C#的首席架构 ...

  8. datatables中的Options总结(2)

    datatables中的Options总结(2) 五.datatable,列 columnDefs.targets 分配一个或多个列的列定义. columnDefs 设置列定义初始化属性. colum ...

  9. CentOS7上安装QGIS

    1.加入YUM源 rpm -Uvh http://download.fedoraproject.org/pub/epel/7/x86_64/e/epel-release-7-8.noarch.rpm ...

  10. React Native学习笔记之2

    1:如何创建一个react native工程 首先进入到指定文件夹里面,然后在终端执行react-native init ReactNativeProject :其中ReactNativeProjec ...