前言
很多人都知道我們在做FineUI控件庫,在這 9 年多的時間里,在和瀏覽器無數次的交往中,也發現了多個瀏覽器自身的BUG,并公開出來方便大家查閱:
- 分享IE7一個神奇的BUG(不是封閉標簽的問題,的確是IE7的BUG)
- Chrome53 最新版驚現無厘頭卡死 BUG!
- Chrome最新版(53-55)再次爆出BUG!
- 三招搞死你的IE11,可重現代碼下載(IE Crash keyframes iframe)!
這類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下出現需要滿足如下三個條件:
- 設置CSS全局屬性:box-sizing: border-box
- HTML標簽為:fieldset
- 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 布局中,由于當前頁面是占據整個屏幕的,所以寬度和高度是從外而內設置的。上面圖片中經歷了這么一個推理過程:
- 根據頁面的高度設置最外層節點的高度
- 一層一層向內推進,可計算出fieldset的高度為135px
- 通過JS設置fieldset高度等于135px
- 此時獲取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>
最終效果圖
點贊
喜歡三石的文章,你就給個推薦唄!
文章列表