【原创】抓个Firefox的小辫子,围观群众有:Chrome、Edge、IE8-11
前言
很多人都知道我们在做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页面重现了这个问题:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | <! 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 标签设置高度后,立即获取高度无效!!!
这个简单的示例中,如果把:
1 2 3 | < fieldset id="fieldset1" style="border:solid 1px red;width:500px;position:absolute;top:0;left:0;"> < legend >fieldset</ legend > </ fieldset > |
改为:
1 2 3 | < 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进行处理:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | <! 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 > |
最终效果图
点赞
喜欢三石的文章,你就给个推荐呗!
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· NetPad:一个.NET开源、跨平台的C#编辑器
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验