各浏览器对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 相关文章推荐
JQUERY THICKBOX弹出层插件
Aug 30 Javascript
HTML代码中标签的全部属性 中文注释说明
Mar 26 Javascript
JavaScript 高级语法介绍
Jun 15 Javascript
jQueryUI写一个调整分类的拖放效果实现代码
May 10 Javascript
用innerhtml提高页面打开速度的方法
Aug 02 Javascript
angularjs学习笔记之双向数据绑定
Sep 26 Javascript
js获取页面及个元素高度、宽度的代码
Apr 26 Javascript
Bootstrap媒体对象的实现
May 01 Javascript
JS中判断null的方法分析
Nov 21 Javascript
JSON基本语法及与JavaScript的异同实例分析
Jan 04 Javascript
如何基于layui的laytpl实现数据绑定的示例代码
Apr 10 Javascript
jQuery cookie的公共方法封装和使用示例
Jun 01 jQuery
给事件响应函数传参数的四种方式小结
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
国产动画《伍六七》原声大碟大卖,啊哈娱乐引领音乐赋能IP的新尝试
2020/03/08 国漫
无刷新动态加载数据 滚动条加载适合评论等页面
2013/10/16 PHP
php使用cookie保存用户登录的用户名实例
2015/01/26 PHP
PHP批量去除BOM头内容信息代码
2016/03/11 PHP
CSDN轮换广告图片轮换效果
2007/03/27 Javascript
一起来写段JS drag拖动代码
2010/12/09 Javascript
图片延迟加载的实现代码(模仿懒惰)
2013/03/29 Javascript
让js弹出窗口居前显示的实现方法
2013/07/10 Javascript
我的Node.js学习之路(一)
2014/07/06 Javascript
jQuery oLoader实现的加载图片和页面效果
2015/03/14 Javascript
js浏览器html5表单验证
2016/10/17 Javascript
vue中简单弹框dialog的实现方法
2018/02/26 Javascript
JavaScript数组排序小程序实现解析
2020/01/13 Javascript
解决echarts echarts数据动态更新和dataZoom被重置问题
2020/07/20 Javascript
[00:57]深扒TI7聊天轮盘语音出处5
2017/05/11 DOTA
使用Python构建Hopfield网络的教程
2015/04/14 Python
Python fileinput模块使用实例
2015/06/03 Python
python timestamp和datetime之间转换详解
2017/12/11 Python
python 读入多行数据的实例
2018/04/19 Python
Python实现将通信达.day文件读取为DataFrame
2018/12/22 Python
python pandas模块基础学习详解
2019/07/03 Python
python英语单词测试小程序代码实例
2019/09/09 Python
python getpass模块用法及实例详解
2019/10/07 Python
python 中Arduino串口传输数据到电脑并保存至excel表格
2019/10/14 Python
Python自动巡检H3C交换机实现过程解析
2020/08/14 Python
DERMAdoctor官网:美国著名皮肤护理品牌
2019/07/06 全球购物
SmartBuyGlasses德国:购买太阳镜和眼镜
2019/08/20 全球购物
工程力学硕士生的自我评价范文
2013/11/16 职场文书
函授毕业生的自我鉴定
2013/11/26 职场文书
党支部书记先进事迹
2014/01/17 职场文书
2013年研究生毕业感言
2014/02/06 职场文书
环保建议书200字
2014/05/14 职场文书
声乐专业大学生职业生涯规划书:理想的未来需要自己去打造
2014/09/20 职场文书
国际贸易本科毕业生求职信
2014/09/26 职场文书
2014年干部培训工作总结
2014/12/17 职场文书
校运会广播稿
2015/08/19 职场文书