关于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

关于onscroll函数兼容各浏览器的方法分析的更多相关文章

  1. 【转】向HTML中插入视频并兼容所有浏览器的方法

    原文地址:http://www.jb51.net/web/168548.html 向HTML中插入视频有两种方法,一种是古老的object标签,一种是html5中的video标签,前者兼容性相对好些, ...

  2. 获取scrollTop兼容各浏览器的方法,以及body和documentElement

    1.各浏览器下 scrollTop的差异 IE6/7/8: 对于没有doctype声明的页面里可以使用  document.body.scrollTop 来获取 scrollTop高度 : 对于有do ...

  3. 【转】获取scrollTop兼容各浏览器的方法,以及body和documentElement是啥?

    1.各浏览器下 scrollTop的差异 IE6/7/8: 对于没有doctype声明的页面里可以使用  document.body.scrollTop 来获取 scrollTop高度 : 对于有do ...

  4. 兼容ie浏览器的方法

    让IE6 IE7 IE8 IE9 IE10 IE11支持Bootstrap的解决方法   最近做一个Web网站,之前一直觉得bootstrap非常好,这次使用了bootstrap3,在chrome,f ...

  5. JS兼容IE浏览器的方法

    背景 系统需要兼容蛋疼的IE6... 解决方案 *{ 兼容IE6-8 }* <!--[if lt IE 9]> <script src="@{'/public/mng/ja ...

  6. 让bind函数支持IE8浏览器的方法

    bind函数在IE8下是不支持的,只需要在你的js文件中加入如下代码就可以支持IE8 //让bind函数支持IE8 if (!Function.prototype.bind) { Function.p ...

  7. 兼容所有浏览器的CSS3圆角

    兼容所有浏览器的CSS3圆角      解决CSS3圆角兼容所有浏览器的方法.本文提到了一种很不错的实现跨浏览器圆角的解决方案,但是说的不够全面,前端观察最近将整理更多更全面的资源给大家,敬请期待. ...

  8. Css:背景色透明,内容不透明之终极方法!兼容所有浏览器

    转载 http://www.cnblogs.com/jikey/archive/2012/08/31/2665880.html <!DOCTYPE html PUBLIC "-//W3 ...

  9. 使用text-align:justify,让内容两端对齐,兼容IE及主流浏览器的方法

    如果不喜欢看分析过程,可以跳到最后看最终兼容方案 史前方法: 以前实现两端对齐是这样的: <p class="box1">密  码</p> <p cl ...

随机推荐

  1. bzoj P4870: [Shoi2017]组合数问题——solution

    题意:求解—— $$(C^{r}_{nk}+C^{r+k}_{nk}+C^{r+2k}_{nk}+...+C^{r+(n-1)k}_{nk}+...)mod(P)$$ 其中$C^{m}_{n}$表示从 ...

  2. 前端日报-20160527 underscore 源码解读

    underscore 源码解读 API文档浏览器 JavaScript 中加号操作符细节 抛弃 jQuery,拥抱原生 JS 从 0 开始学习 GitHub 系列之「加入 GitHub」 js实现克隆 ...

  3. 用js获取当前月份的天数

    在获取每月天数的时候,一般都是存储到一个数组中进行获取,但是如果是二月份的话就需要首先判断是否闰年,再确定是28还是29了. js可以通过Date对象很方便的获取到每月的天数,在初始化Date对象时, ...

  4. JS 面试题 实践一

    1.完成 extname 函数,它会接受一个文件名作为参数,你需要返回它的扩展名. 例如,输入 emoji.png,返回 .png. const extname = (filename) => ...

  5. Atitit.播放系统的选片服务器,包厢记时系统 的说明,教程,维护,故障排查手册p825

    Atitit.播放系统的选片服务器,包厢记时系统 的说明,教程,维护,故障排查手册p825 1. 播放系统服务器方面的维护2 1.1. 默认情况下,已经在系统的启动目录下增加了俩个启动项目2 1.2. ...

  6. 如何利用API导出带有页眉页脚的excel

     在报表中设置的页眉页脚在页面中是看不到的,如下图: 页面中的效果: 在打印的时候,可以看到页眉页脚的效果: 那么,如果将页眉页脚导入到导出的excel中呢.我们可以通过API来进行设置: < ...

  7. 报表导出excel方式介绍

     报表导出excel提供了四种方式,在单元格属性"其他/导出excel方式"可以选择,如下图 一是导出缺省值:报表中的单元格包含两个值,一个真实值一个显示值,但是在excel中 ...

  8. SqlSugarClientHelper

    using SqlSugar; using System; using System.Collections.Generic; using System.Configuration; using Sy ...

  9. BootStrap selectpicker后台动态绑定数据

    项目使用BootStrap设置select时,不能动态加载,使用以下方法可以解决. //获得全部订单信息(订单ID,订单名称) function GetAllOrders(obj) { $.ajax( ...

  10. 三、vue如何配置路由 、获取路由的参数、部分刷新页面、缓存页面

        1.路由配置:所有的启动文件都在最初始的main.js文件里面,这个文件中首先需要引入: 2.路由文件配置说明: 3.如何获取页面url的参数? this.$route.query 4.页面之 ...