各浏览器对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 相关文章推荐
jQeury淡入淡出需要注意的问题
Sep 08 Javascript
JQuery onload、ready概念介绍及使用方法
Apr 27 Javascript
网站接入QQ登录的两种方法
Jul 22 Javascript
JQuery中Text方法用法实例分析
May 18 Javascript
JavaScript AOP编程实例
Jun 16 Javascript
详解本地Node.js服务器作为api服务器的解决办法
Feb 28 Javascript
详解vue axios中文文档
Sep 12 Javascript
Vue异步加载about组件
Oct 31 Javascript
详解如何使用koa实现socket.io官网的例子
Nov 04 Javascript
vuex存储复杂参数(如对象数组等)刷新数据丢失的解决方法
Nov 05 Javascript
JS实现小星星特效
Dec 24 Javascript
微信小程序开发(一):服务器获取数据列表渲染操作示例
Jun 01 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
如何将数据从文本导入到mysql
2006/10/09 PHP
Snoopy类使用小例子
2008/04/15 PHP
PHP分多步骤填写发布信息的简单方法实例代码
2012/09/23 PHP
PHP文件上传主要代码讲解
2013/09/30 PHP
推荐5款跨平台的PHP编辑器
2014/12/25 PHP
PHP论坛实现积分系统的思路代码详解
2020/06/01 PHP
学习ExtJS 访问容器对象
2009/10/07 Javascript
js 巧妙去除数组中的重复项
2010/01/25 Javascript
JavaScript XML和string相互转化实现代码
2011/07/04 Javascript
JavaScript中的数学运算介绍
2014/12/29 Javascript
JavaScript的类型、值和变量小结
2015/07/09 Javascript
基于jQuery实现网页打印功能
2015/12/01 Javascript
jquery实现左右无缝轮播图
2020/07/31 Javascript
把普通对象转换成json格式的对象的简单实例
2016/07/04 Javascript
JavaScript数据结构之广义表的定义与表示方法详解
2017/04/12 Javascript
详解Node.js模板引擎Jade入门
2018/01/19 Javascript
vue中过滤器filter的讲解
2019/01/21 Javascript
vue中使用mxgraph的方法实例代码详解
2019/05/17 Javascript
详解基于element的区间选择组件校验(交易金额)
2021/01/07 Javascript
jquery实现穿梭框功能
2021/01/19 jQuery
[44:40]KG vs LGD 2019国际邀请赛小组赛 BO2 第一场 8.15
2019/08/16 DOTA
windows下python之mysqldb模块安装方法
2017/09/07 Python
Python随机生成均匀分布在单位圆内的点代码示例
2017/11/13 Python
Python序列化pickle模块使用详解
2020/03/05 Python
Python如何获取文件指定行的内容
2020/05/27 Python
python 检测图片是否有马赛克
2020/12/01 Python
耐克中国官方商城:Nike中国
2018/10/18 全球购物
Weblogic的布署方式
2013/08/23 面试题
华三通信H3C面试题
2015/05/15 面试题
毕业生造价工程师求职信
2013/10/17 职场文书
计算机软件个人的自荐信范文
2013/12/01 职场文书
正风肃纪查摆剖析材料
2014/10/10 职场文书
教师听课评语大全
2014/12/31 职场文书
2015年教研室工作总结范文
2015/05/23 职场文书
运动会宣传语
2015/07/13 职场文书
Win11跳过联网界面创建本地管理账户的3种方法
2022/04/20 数码科技