❗ 本文最后更新于 2625 天前,文中所描述的信息可能已发生改变,请谨慎使用。
相信大部分前端同学都知道,Webkit 对于页面滚动条位置,没有按照标准处理。以下是摘自 W3Help 的说明:
在混杂模式下,由于所有浏览器均使用 document.body.scrollTop 获取页面的垂直滚动条的位置,所以不会出现兼容性问题。而在标准模式下,由于 Chrome 与 Safari 仍然使用 document.body.scrollTop,而对于 document.documentElement.scrollTop 返回为 0。
也就是说对 Webkit 来说,无论是混杂模式还是标准模式,它都认为页面滚动元素是 BODY
;而其它浏览器只有在混杂模式下,才会认为页面滚动元素是 BODY
,标准模式下则是 HTML
。这是 Webkit 一直就存在的 Bug。
各种 JS 库通常都会抹平不同浏览器及不同模式下的这些差异,统一提供获取或设置 scrollTop / scrollLeft 的接口,所以这个问题往往不会暴露出来。具体的兼容方案很简单,略过不提。但需要注意一点,千万不要使用 UA 检测来解决这个问题,如果针对 UA 包含 webkit
的浏览器统一使用 document.body 那就有问题,后面会讲到原因。
最近我发现了一个诡异的现象:在我的 Chrome 里需要通过 document.documentElement 元素获取页面滚动条位置。原本我以为是 Chrome 修改了实现,保持跟标准一致;但奇怪的是,我的 Chrome Canary 还是老样子,别人跟我版本一致的 Chrome 也还是老样子。
为了彻底搞明白这件事情,我在 Chromium Bug 系统中开始了搜索。很快,我找到关于此问题的 BUG 记录。这条记录最后回复更新于几天前,说受其它问题影响,「页面滚动元素错误」这个 BUG 虽然已经修复,但是并没有推到主版本。实际上,Chromium 团队发现改为标准实现后,一些广泛使用的扩展和一些大站会受影响,所以决定先放一放。
看来即便是技术激进的 Google,也不得不背负一些沉重的历史包袱。既然是这样,难道我的 Chrome 已经穿越到了未来?我百思不得其解。
也不知道过了多久,我突然灵光乍现,想到某次我为了测试一个功能,开启了 chrome://flags
中的「Experimental Web Platform features(实验性网络平台功能)」选项,莫非是这个原因。果然,也不知道从哪个版本开始,Chromium 偷偷修复了这个 BUG —— 只是默认没有启用 —— 除非用户主动打开这个实验性开关。
聊到这里,顺便再说说 document.scrollingElement 这个属性。可能是浏览器厂商们也觉得现在的页面滚动元素太乱,一会儿 BODY 一会儿 HTML,跟页面模式有关,还跟 Webkit 的遗留 BUG 有关,于是搞出来这么个东西。根据 MDN 的介绍:
Document 的 scrollingElement 是一个只读属性,始终指向页面滚动元素。via
这样倒也方便,只是目前它的支持度还很差,需要版本比较高的浏览器:
- Chrome 44+(PC、Mobile);
- Safari 9+(PC、Mobile);
- Firefox 47+(PC、Mobile);
Chrome 在向标准靠拢之前就支持了这个属性,也是一件好事。至少,在只需要支持 Webkit 的场合,这样获取页面滚动元素就没问题了:
var rootElement = document.scrollingElement || document.body;
最后,以简单小结来结束本文:1)如果发现自己的浏览器有一些跟别人不一样的特性,如果版本相同,那么很可能是受到某些配置项的影响;2)随着时间的推移,Blink(Chrome)和 Webkit(Safari)的差距会越来越大,平时可以多关注下浏览器厂商的升级公告和新的 WEB 标准。
update:从 Chrome 61 开始,标准模式中
document.scrollingElement
已被修正为document.documentElement
。换句话说,这个版本开始标准模式中document.body.scrollTop
始终都等于 0。
扩展阅读:Dev.Opera Blog : Fixing the scrollTop bug。
本文链接:https://mailseason.com/post/document-scrollingelement-in-chrome.html,参与评论 »
--EOF--
发表于 2016-04-16 15:05:13,并被添加「Chrome、Webkit、WEB、标准」标签,最后修改于 2017-09-14 11:37:44。查看本文 Markdown 版本 »
专题「浏览器」的其他文章 »
- iOS 10 Safari 视频播放新政策 (Oct 07, 2016)
- 域名小知识:Public Suffix List (Nov 28, 2015)
- window.opener.location 安全风险讨论 (Oct 09, 2015)
- 使用 SRI 增强 localStorage 代码安全 (Sep 26, 2015)
- Subresource Integrity 介绍 (Sep 23, 2015)
- 移动 Web 与 JavaScript 定时器 (Mar 27, 2014)
- Chrome 和 Web Fonts 二三事 (Mar 24, 2014)
- Webkit 异步加载 CSS 的奇怪现象 (Dec 25, 2013)
- 小成本实现部分选中的复选框 (Dec 22, 2013)
- Chrome 滚动条冻结现象 (Dec 02, 2013)
Comments
Waline 评论加载中...