各浏览器对document.getElementById等方法的实现差异解析

所属分类: 网络编程 / JavaScript 阅读数: 671
收藏 0 赞 0 分享

所有Web前端同仁对 document.getElementById 都非常熟悉了。开发过程中经常需要用其获取页面id为xx的元素,自从元老级JS库Prototype流行后,都喜欢这么简写它

复制代码 代码如下:

// 方式1
function $(id){ return document.getElementById(id); }

有没有人想过为什么要这么写,而不用下面的方式写呢?
复制代码 代码如下:

// 方式2
var $ = document.getElementById;

这么写的$更简洁啊,也很明了,将document的方法getElementById赋值给变量$,用$去获取页面id为xx的元素。实际上方式2在IE6/7/8中是可行的(IE9中有些变动),Firefox/Safari/Chrome/Opera则行不通。还请自行测试。

为什么Firefox/Safari/Chrome/Opera 方式2获取就不行呢,原因是这些浏览器中getElementById方法内部实现中需依赖this(document),IE则不需要this。或者说方式2在Firefox/Safari/Chrome/Opera中调用时说丢失了this,以下是个简单示例

复制代码 代码如下:

// 定义一个函数show
function show(){alert(this.name);}

// 定义一个p对象,有name属性
var p = {name:'Jack'};

show.call(p); // -> 'Jack'
show(); // -> ''
show.call(null); // -> ''<BR>

可以看到show的实现中依赖this(简单说方法体中使用了this),因此调用时的环境(执行上下文)如果没有name属性,则得不到期望的结果。
换句话说,IE6/7/8实现document.getElementById时没有用到this,而 IE9/Firefox/Safari/Chrome/Opera 需要用到this,这里的this正是document对象。直接调用方式2时内部的 this却是window对象,所以造成方式2在 Firefox/Safari/Chrome/Opera 不能根据id来正常获取元素。

如果将document.getElementById的 执行环境换成了document而非window,则可以正常的使用$了。如下

复制代码 代码如下:

// 修复document.getElementById
document.getElementById = (function(fn){
    return function(){ 
        return fn.apply(document,arguments);
    };
})(document.getElementById);

// 修复后赋值给$,$可正常使用了
var $ = document.getElementById;

再次,ECMAScript5 中为function新增的 bind 方法可以实现同样的效果
复制代码 代码如下:

// 方式3
var $ = document.getElementById.bind(document);

但目前方式3只有IE9/Firefox/Chrome/支持。

分析了getElementById的情况,下面的一些方法在各浏览器中的差异原因就很好明白了

复制代码 代码如下:

var prinf = document.write;
prinf('<h3>Test prinf</h3>'); // IE6/7/8可运行,其它浏览器报错

var prinfln = document.writeln;
prinfln('<h3>Test prinfln</h3>'); // IE6/7/8可运行,其它浏览器报错

var reload = location.reload;
reload(); // IE6/7/8可运行,其它浏览器报错

var go = history.go; 
go(-2); // IE6/7/8可运行,其它浏览器报错

更多精彩内容其他人还在看

JavaScript this关键字指向常用情况解析

这篇文章主要介绍了JavaScript this关键字指向常用情况解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
收藏 0 赞 0 分享

Vue-cli打包后如何本地查看的操作

这篇文章主要介绍了Vue-cli打包后如何本地查看的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
收藏 0 赞 0 分享

vue cli 3.0通用打包配置代码,不分一二级目录

这篇文章主要介绍了vue cli 3.0通用打包配置代码,不分一二级目录,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
收藏 0 赞 0 分享

JavaScript事件循环及宏任务微任务原理解析

这篇文章主要介绍了JavaScript事件循环及宏任务微任务原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
收藏 0 赞 0 分享

关于vue-cli3打包代码后白屏的解决方案

这篇文章主要介绍了关于vue-cli3打包代码后白屏的解决方案,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
收藏 0 赞 0 分享

vue打包静态资源后显示空白及static文件路径报错的解决

这篇文章主要介绍了vue打包静态资源后显示空白及static文件路径报错的解决,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
收藏 0 赞 0 分享

vue-cli3访问public文件夹静态资源报错的解决方式

这篇文章主要介绍了vue-cli3访问public文件夹静态资源报错的解决方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
收藏 0 赞 0 分享

JS继承实现方法及优缺点详解

这篇文章主要介绍了JS继承实现方法及优缺点详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
收藏 0 赞 0 分享

vue或react项目生产环境去掉console.log的操作

这篇文章主要介绍了vue或react项目生产环境去掉console.log的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
收藏 0 赞 0 分享

解决vue组件没显示,没起作用,没报错,但该显示的组件没显示问题

这篇文章主要介绍了解决vue组件没显示,没起作用,没报错,但该显示的组件没显示问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
收藏 0 赞 0 分享
查看更多