关于onscroll函数兼容各浏览器的方法分析

关于window.onscroll函数兼容各浏览器的方法分析

1、当前文档的渲染模式是决定onscroll函数兼容性根本原因

目前浏览器的排版引擎有三种模式:怪异模式(Quirks mode)、接近标准模式(Almost standards mode)、以及标准模式(Standards mode)。对HTML文件来说,浏览器使用文件开头的 DOCTYPE 来决定用怪异模式处理或标准模式处理。如果文档没有声明DOCTYPE,会令浏览器触发怪异模式。例如<!DOCTYPE html>,是所有可用的DOCTYPE之中最简单的,而且是HTML5 所推荐的。在 HTML5中,DOCTYPE 唯一的作用是启用标准模式。更早期的 HTML 标准会附加其他意义,但没有任何浏览器会将 DOCTYPE 用于怪异模式和标准模式之间互换以外的用途。

2、获取当前文档的渲染模式

代码如下:

mode = document.compatMode;
  • 如果文档处于“怪异模式(Quirks mode)”,则该属性值为"BackCompat"
  • 如果文档处于“标准模式(Standards mode)”或者“准标准模式(almost standards mode)”,则该属性为"CSS1Compat"

3、代码分析

就拿获取scrollTop来举例:

  • document.body.scrollTop在当前文档处于“怪异模式(Quirks mode)”(即上段代码中mode = "BackCompat")使用,当HTML文档没有声明DOCTYPE的时候,浏览器可以识别。
  • document.documentElement.scrollTop在当前文档处于“标准模式(Standards mode)”或者“准标准模式(almost standards mode)”(即上段代码中mode = "CSS1Compat")使用,当HTML文档正确声明DOCTYPE的时候,就可能会启用标准模式,是否启用取决于浏览器本身。
  • window.pageYOffset最为特殊,并不取决于文档的渲染模式,而是取决于浏览器本身是否存在此属性。

各浏览器对上述代码兼容情况:

  1. IE6/7/8:没有doctype声明的html文档使用  document.body.scrollTop,否则使用document.documentElement.scrollTop。这些版本的浏览器中window.pageYOffset属性是undefined,因此无效。
  2. Google Chrome,Firefox,IE9+: document.body.scrollTop 和 document.documentElement.scrollTop 使用方式同上,但window.pageYOffset 无论doctype是否声明,浏览器都可以识别。(早前的chrome只能识别document.body也就是documentElement对应body标签,自用chrome更新63以上版本以后正确doctype文档声明document.body.scrollTop恒为0,document.documentElement.scrollTop正常,chrome也没有早前那样特立独行了)。
  3. Safari: 浏览器特殊,目前只有window.pageYOffset有效。

MDN上完整的兼容性代码如下:

var supportPageOffset = window.pageXOffset !== undefined;
var isCSS1Compat = ((document.compatMode || "") === "CSS1Compat");

var x = supportPageOffset ? window.pageXOffset : isCSS1Compat ? document.documentElement.scrollLeft : document.body.scrollLeft;
var y = supportPageOffset ? window.pageYOffset : isCSS1Compat ? document.documentElement.scrollTop : document.body.scrollTop;

 当然还有最终写法:

var scrollTop = document.documentElement.scrollTop || window.pageYOffset 
                    || document.body.scrollTop;

注意放置顺序:window.pageYOffset被放置在 || 的中间位置。 
因为当 数字0 与 undefine 进行"||"运算时,系统默认返回最后一个值。即"||"运算中 "0  ||  undefine == undefine" ; 
当页面滚动条刚好在最顶端,即scrollTop值为 0 时。  window.pageYOffset(IE9<)会返回为 undefine ,此时将window.pageYOffset放在"||"运算最后面时, scrollTop 返回 undefine (0 || 0 || undefine == undefine),  浏览器会报错。
而其他浏览器 无论 scrollTop 赋值或运算顺序如何都不会返回 undefine.  可以安全使用。

参考

https://developer.mozilla.org/zh-CN/docs/Web/HTML/Quirks_Mode_and_Standards_Mode

https://developer.mozilla.org/zh-CN/docs/Web/API/Document/compatMode

https://developer.mozilla.org/zh-CN/docs/Web/API/Window/scrollY

http://www.cnblogs.com/ckmouse/archive/2012/01/30/2332076.html

 

posted @ 2018-10-26 22:46  陆三九  阅读(1026)  评论(0编辑  收藏  举报