文章出處

前言

很多人都知道我們在做FineUI控件庫,在這 9 年多的時間里,在和瀏覽器無數次的交往中,也發現了多個瀏覽器自身的BUG,并公開出來方便大家查閱:

這類BUG之所以被大家所深惡痛絕,在于其隱蔽性,很多時候不能用常規的邏輯去分析。另一個原因的開發人員一般都很善良,出現問題總是從自身找原因,很少會懷疑到IDE,瀏覽器這些開發工具上面來。

事實情況是,瀏覽器也是開發人員開發的,是個軟件就有BUG!

 

今天公開的這個Firefox BUG一直長期存在,最新的 Firefox Quantum 也位列其中,下面就聽我詳細道來......

 

發現問題

昨天一個客戶向我們反饋了一個問題,頁面初始時表格未顯示,等頁面回發后表格才顯示出現。奇怪的是,這個問題僅在Firefox下出現,Chrome、IE下是正常的。

下面是和客戶溝通的截圖:

 

接到反饋后,我們立即進行了測試,在Chrome,Edge,IE下頁面第一次打開是這樣的:

 

但是在Firefox中,頁面第一次打開時流程信息分組面板(GroupPanel)中的表格不見了:

 

只有在頁面回發后,才會顯示出來。初步調試可以看出,Firefox下頁面第一次加載時表格外部容器的高度不對:

 

分析問題

由于這個問題只在Firefox下出現,其他瀏覽器Chrome、Edge、IE8-11均顯示正常,因此我們初步判斷是Firefox的BUG導致FineUI布局時計算外部容器錯誤。

為了排除這是Firefox 57.0 新版引入的問題,我們還特意下載了一個老版本:

 

結果發現,Firefox老版本存在相同的問題,看來這個問題一直存在。

 

經過一段緊張的排查,我們終于通過一個簡單的HTML頁面重現了這個問題:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <script src="https://code.jquery.com/jquery-1.11.3.js"></script>
    <style>
        *, :after, :before {
            -webkit-box-sizing: border-box;
            -moz-box-sizing: border-box;
            box-sizing: border-box;
        }
    </style>
</head>
<body>
    <fieldset id="fieldset1" style="border:solid 1px red;width:500px;position:absolute;top:0;left:0;">
        <legend>fieldset</legend>
    </fieldset>

    <script>

        $(function () {
            $('#fieldset1').height(200);
            alert(parseInt($('#fieldset1').height(), 10));
        });

    </script>
</body>
</html>  

Firefox下測試:

 

Chrome下測試:

 

Edge下測試:

 

IE11-IE8下測試:

 

 

經過對代碼的進一步測試發現,這個BUG在Firefox下出現需要滿足如下三個條件:

  1. 設置CSS全局屬性:box-sizing: border-box
  2. HTML標簽為:fieldset
  3. fieldset絕對定位:position:absolute

當同時滿足這三個條件時,通過JS對 fieldset 標簽設置高度后,立即獲取高度無效!!!

這個簡單的示例中,如果把:

<fieldset id="fieldset1" style="border:solid 1px red;width:500px;position:absolute;top:0;left:0;">
        <legend>fieldset</legend>
</fieldset>  

改為:

<div id="fieldset1" style="border:solid 1px red;width:500px;position:absolute;top:0;left:0;">
        
</div>  

則Firefox下就不會有問題:

 

而我們的 FineUI 的 GroupPanel 控件正是滿足了這三個條件,才巧遇了這個Firefox一直存在的BUG:

在FineUI 布局中,由于當前頁面是占據整個屏幕的,所以寬度和高度是從外而內設置的。上面圖片中經歷了這么一個推理過程:

  1. 根據頁面的高度設置最外層節點的高度
  2. 一層一層向內推進,可計算出fieldset的高度為135px
  3. 通過JS設置fieldset高度等于135px
  4. 此時獲取fieldset的高度卻不是135px,導致設置表格的外部容器的高度出現偏差(9.5px)

 

解決問題

當然最好的解決辦法就是等Firefox更新了,什么時候修正這個BUG。但是你能指望Firefox什么時候修正這個問題呢?既然已經存在幾年的時間了,很有可能繼續存在下去。

從另一個角度講,用老版本Firefox的用戶怎么辦?問題還是要解決,不能改變別人,只要拿自己動手了。

在經歷了那么多瀏覽器BUG之后,我們已經很淡定了,不就是設置節點屬性后不更新么,我們來強制更新一把!

下面的方案可以很好的解決這個問題,并且僅對Firefox進行處理:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <script src="https://code.jquery.com/jquery-1.11.3.js"></script>
    <style>
        *, :after, :before {
            -webkit-box-sizing: border-box;
            -moz-box-sizing: border-box;
            box-sizing: border-box;
        }
    </style>
</head>
<body>
    <fieldset id="fieldset1" style="border:solid 1px red;width:500px;position:absolute;top:0;left:0;">
        <legend>fieldset</legend>
    </fieldset>

    <script>

        $(function () {
            $('#fieldset1').height(200);

            
            if (/firefox/i.test(window.navigator.userAgent)) {
                // 強制瀏覽器重新繪制fieldset節點
                var fieldsetNode = $('#fieldset1');
                fieldsetNode.css('overflow', 'auto');
                fieldsetNode[0].scrollWidth;
                fieldsetNode.css('overflow', 'hidden');
            }
            

            alert(parseInt($('#fieldset1').height(), 10));
        });

    </script>
</body>
</html>

 

最終效果圖

 

點贊

喜歡三石的文章,你就給個推薦唄!

  

 


文章列表


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()