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


Posted in Javascript onDecember 05, 2013

所有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 相关文章推荐
javascript学习笔记(七)利用javascript来创建和存储cookie
Apr 08 Javascript
IE 当eval遇上function的处理
Aug 09 Javascript
javascript右下角弹层及自动隐藏(自己编写)
Nov 20 Javascript
基于jQuery实现返回顶部实例代码
Jan 01 Javascript
js print打印网页指定区域内容的简单实例
Nov 01 Javascript
深入学习jQuery中的data()
Dec 22 Javascript
Vue组件tree实现树形菜单
Apr 13 Javascript
Node.Js生成比特币地址代码解析
Apr 21 Javascript
react中实现搜索结果中关键词高亮显示
Jul 31 Javascript
微信小程序实现定位及到指定位置导航的示例代码
Aug 20 Javascript
swiper Scrollbar滚动条组件详解
Sep 08 Javascript
vue中利用iscroll.js解决pc端滚动问题
Feb 15 Javascript
给事件响应函数传参数的四种方式小结
Dec 05 #Javascript
弹出最简单的模式化遮罩层的js代码
Dec 04 #Javascript
js如何设置在iframe框架中指定div不显示
Dec 04 #Javascript
jquery动态改变onclick属性导致失效的问题解决方法
Dec 04 #Javascript
javascript设置金额样式转换保留两位小数示例代码
Dec 04 #Javascript
下拉列表select 由左边框移动到右边示例
Dec 04 #Javascript
JS获得QQ号码的昵称,头像,生日的简单实例
Dec 04 #Javascript
You might like
PHP静态类
2006/11/25 PHP
攻克CakePHP系列一 连接MySQL数据库
2008/10/22 PHP
PHP实现读取一个1G的文件大小
2013/08/24 PHP
PHP输出缓存ob系列函数详解
2014/03/11 PHP
PHP小教程之实现链表
2014/06/09 PHP
php防止sql注入之过滤分页参数实例
2014/11/03 PHP
php获得文件大小和文件创建时间的方法
2015/03/13 PHP
Confirmer JQuery确认对话框组件
2010/06/09 Javascript
UserData用法总结 lanyu出品
2010/07/01 Javascript
js日期时间补零的小例子
2013/03/05 Javascript
AngularJS控制器之间的通信方式详解
2016/11/03 Javascript
微信小程序购物商城系统开发系列-目录结构介绍
2016/11/21 Javascript
jQuery实现两个select控件的互移操作
2016/12/22 Javascript
在vue-cli脚手架中配置一个vue-router前端路由
2017/07/03 Javascript
JS倒计时实例_天时分秒
2017/08/22 Javascript
新手简单了解vue
2019/05/29 Javascript
基于循环神经网络(RNN)的古诗生成器
2018/03/26 Python
python使用pymongo操作mongo的完整步骤
2019/04/13 Python
Python利用lxml模块爬取豆瓣读书排行榜的方法与分析
2019/04/15 Python
python操作kafka实践的示例代码
2019/06/19 Python
详解解决Python memory error的问题(四种解决方案)
2019/08/08 Python
在pytorch中查看可训练参数的例子
2019/08/18 Python
基于python求两个列表的并集.交集.差集
2020/02/10 Python
python实现飞机大战项目
2020/03/11 Python
详解python如何引用包package
2020/06/07 Python
深入分析python 排序
2020/08/24 Python
GWebs公司笔试题
2012/05/04 面试题
电子技术专业中专生的自我评价
2013/12/17 职场文书
中式面点餐厅创业计划书
2014/01/29 职场文书
小学向国旗敬礼活动方案
2014/09/27 职场文书
医院护士工作检讨书
2014/10/26 职场文书
明星邀请函
2015/02/02 职场文书
终止劳动合同通知书
2015/04/16 职场文书
工会文体活动总结
2015/05/07 职场文书
安娜卡列尼娜观后感
2015/06/11 职场文书
行政复议决定书
2015/06/24 职场文书