• 【原创】Chrome最新版(53-55)再次爆出BUG!


    前言

    今年十月份,我曾发布一篇文章《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;400px;height:200px;">
            <iframe id="frame1" style="100%;height:100%;border:none;" src="./page2.html"></iframe>
            <iframe id="frame2" style="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 的 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;400px;height:200px;">
            <iframe id="frame1" style="400px;height:200px;border:none;" src="./page2.html"></iframe>
            <iframe id="frame2" style="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;400px;height:200px;" id="container1">
            <iframe id="frame1" style="400px;height:200px;border:none;" src="./page2.html"></iframe>
            <iframe id="frame2" style="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;400px;height:200px;" id="container1">
            <iframe id="frame1" style="100%;height:100%;border:none;" src="./page2.html"></iframe>
            <iframe id="frame2" style="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;400px;height:200px;" id="container1">
            <iframe id="frame1" style="100%;height:100%;border:none;" src="./page2.html"></iframe>
            <iframe id="frame2" style="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

  • 相关阅读:
    监视和调整硬件性能
    ASP.NET MVC三个重要的描述对象:ActionDescriptor
    REST in Practice
    软硬件错误的排查之道
    OMCS 多媒体连接系统
    逻辑层 vs 物理层
    深入浅出裸测之道单元测试的单元化
    简单的网络爬虫实现
    WCF返回JSON与传入JSON(普通参数或对象)
    .NET程序员的一个礼物——TypeMonster
  • 原文地址:https://www.cnblogs.com/sanshi/p/6138767.html
Copyright © 2020-2023  润新知