各浏览器对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实现的鼠标经过时播放声音
May 18 Javascript
给jqGrid数据行添加修改和删除操作链接(之一)
Nov 04 Javascript
Js数组的操作push,pop,shift,unshift等方法详细介绍
Dec 28 Javascript
JavaScript SetInterval与setTimeout使用方法详解
Nov 15 Javascript
Js 去掉字符串中的空格(实现代码)
Nov 19 Javascript
javascript实现input file上传图片预览效果
Dec 31 Javascript
vue.js选中动态绑定的radio的指定项
Jun 02 Javascript
js CSS3实现卡牌旋转切换效果
Jul 04 Javascript
利用webpack理解CommonJS和ES Modules的差异区别
Jun 16 Javascript
vue实现导航菜单和编辑文本的示例代码
Jul 04 Javascript
js实现移动端图片滑块验证功能
Sep 29 Javascript
JS如何实现在弹出窗口中加载页面
Dec 03 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使之能同时支持GIF和JPEG
2006/10/09 PHP
php仿QQ验证码的实例分析
2013/07/01 PHP
PHP的反射机制实例详解
2017/03/29 PHP
Javascript中eval函数的使用方法与示例
2007/04/09 Javascript
JavaScript 自动完成脚本整理(33个)
2009/10/20 Javascript
Javascript 遍历页面text控件详解
2014/01/06 Javascript
js中top的作用深入剖析
2014/03/04 Javascript
浅谈jquery事件处理
2015/04/24 Javascript
利用Jasmine对Angular进行单元测试的方法详解
2017/06/12 Javascript
jQuery实现倒计时功能 jQuery实现计时器功能
2017/09/19 jQuery
ztree实现左边动态生成树右边为内容详情功能
2017/11/03 Javascript
微信小程序progress组件使用详解
2018/01/31 Javascript
[00:35]DOTA2上海特级锦标赛 VP战队宣传片
2016/03/04 DOTA
Python编写屏幕截图程序方法
2015/02/18 Python
在Python的Flask框架中使用模版的入门教程
2015/04/20 Python
python操作redis的方法
2015/07/07 Python
用 Python 爬了爬自己的微信朋友(实例讲解)
2017/08/25 Python
Python学习之Django的管理界面代码示例
2018/02/10 Python
使用Python监控文件内容变化代码实例
2018/06/04 Python
Python日志模块logging基本用法分析
2018/08/23 Python
Python字典创建 遍历 添加等实用基础操作技巧
2018/09/13 Python
python实现Zabbix-API监控
2018/09/17 Python
python通过安装itchat包实现微信自动回复收到的春节祝福
2020/01/19 Python
python使用QQ邮箱实现自动发送邮件
2020/06/22 Python
如何在python中实现线性回归
2020/08/10 Python
解决pytorch 的state_dict()拷贝问题
2021/03/03 Python
关于 HTML5 的七个传说小结
2012/04/12 HTML / CSS
诗狄娜化妆品官方网站:Stila Cosmetics
2016/12/21 全球购物
英国领先的家庭时尚品牌:Peacocks
2018/01/11 全球购物
德国亚马逊官方网站:Amazon.de
2020/11/15 全球购物
国际政治个人自荐信范文
2013/11/26 职场文书
《爱如茉莉》教后反思
2014/04/12 职场文书
书法大赛策划方案
2014/06/04 职场文书
特此通知格式
2015/04/27 职场文书
负责培养人意见
2015/06/05 职场文书
nginx+lua单机上万并发的实现
2021/05/31 Servers