各浏览器对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 监听textarea中按键事件
Oct 08 Javascript
jquery中表单 多选框的一种巧妙写法
Sep 06 Javascript
JS+CSS简单树形菜单实现方法
Sep 12 Javascript
学习JavaScript设计模式之迭代器模式
Jan 19 Javascript
jQuery实现图片向左向右切换效果的简单实例
May 18 Javascript
基于Layer+jQuery的自定义弹框
May 26 Javascript
javascript正则表达式模糊匹配IP地址功能示例
Jan 06 Javascript
jQuery表格的维护和删除操作
Feb 03 Javascript
微信小程序实战之顶部导航栏(选项卡)(1)
Jun 19 Javascript
微信小程序之发送短信倒计时功能
Aug 30 Javascript
vue中实现滚动加载更多的示例
Nov 08 Javascript
JSONP 的原理、理解 与 实例分析
May 16 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 strcmp使用说明
2010/04/22 PHP
php冒泡排序、快速排序、快速查找、二维数组去重实例分享
2014/04/24 PHP
Thinkphp5结合layer弹窗定制操作结果页面
2017/07/07 PHP
Laravel 5.4向IoC容器中添加自定义类的方法示例
2017/08/15 PHP
js 兼容多浏览器的回车和鼠标焦点事件代码(IE6/7/8,firefox,chrome)
2010/04/14 Javascript
JavaScript 面向对象之命名空间
2010/05/04 Javascript
推荐30个新鲜出炉的精美 jQuery 效果
2012/03/26 Javascript
jquery实现手机发送验证码的倒计时代码
2014/02/12 Javascript
js实现图片从左往右渐变切换效果的方法
2015/02/06 Javascript
js智能获取浏览器版本UA信息的方法
2016/08/08 Javascript
使用vue编写一个点击数字计时小游戏
2016/08/31 Javascript
AngularJS bootstrap启动详解及实例代码
2016/09/14 Javascript
JavaScript的Object.defineProperty详解
2018/07/09 Javascript
JavaScript折半查找(二分查找)算法原理与实现方法示例
2018/08/06 Javascript
vue element upload组件 file-list的动态绑定实现
2019/10/11 Javascript
angular组件间通讯的实现方法示例
2020/05/07 Javascript
微信小程序实现可拖动悬浮图标(包括按钮角标的实现)
2020/12/29 Javascript
JavaScript的一些小技巧分享
2021/01/06 Javascript
[02:22:36]《加油!DOTA》总决赛
2014/09/19 DOTA
[01:01:01]完美世界DOTA2联赛循环赛 GXR vs FTD BO2第一场 10.29
2020/10/29 DOTA
几个提升Python运行效率的方法之间的对比
2015/04/03 Python
python多进程实现进程间通信实例
2017/11/24 Python
Python过滤txt文件内重复内容的方法
2018/10/21 Python
python实现批量注册网站用户的示例
2019/02/22 Python
Python之修改图片像素值的方法
2019/07/03 Python
python tkinter组件摆放方式详解
2019/09/16 Python
基于Python中isfile函数和isdir函数使用详解
2019/11/29 Python
pytorch模型预测结果与ndarray互转方式
2020/01/15 Python
Python批量处理csv并保存过程解析
2020/05/16 Python
南非最受欢迎的时尚品牌:MRP
2016/09/18 全球购物
生物科学专业毕业生求职信
2014/06/02 职场文书
五年级学生期末评语
2014/12/26 职场文书
学雷锋日活动总结
2015/02/06 职场文书
2015年度个人思想工作总结
2015/04/08 职场文书
2015年推普周活动方案
2015/05/06 职场文书
解决mysql模糊查询索引失效问题的几种方法
2021/06/18 MySQL