各浏览器对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 相关文章推荐
jscript之Open an Excel Spreadsheet
Jun 13 Javascript
JS代码优化技巧之通俗版(减少js体积)
Dec 23 Javascript
鼠标移动到图片名上,显示图片的简单实例
Jul 14 Javascript
多种方法判断Javascript对象是否存在
Sep 22 Javascript
jQuery中animate()方法用法实例
Dec 24 Javascript
JavaScript实现删除,移动和复制文件的方法
Aug 05 Javascript
react系列从零开始_简单谈谈react
Jul 06 Javascript
JS 60秒后重新发送验证码的实例讲解
Jul 26 Javascript
Vue.js用法详解
Nov 13 Javascript
微信小程序实现图片上传、删除和预览功能的方法
Dec 18 Javascript
过滤器vue.filters的使用方法实现
Sep 18 Javascript
vuex + keep-alive实现tab标签页面缓存功能
Oct 17 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的curl实现get和post的代码
2008/08/23 PHP
通过php快速统计某个数据库中每张表的数据量
2012/09/04 PHP
配置php网页显示各种语法错误
2013/09/23 PHP
php使用gzip压缩传输js和css文件的方法
2015/07/29 PHP
PHP重定向与伪静态区别
2017/02/19 PHP
不常用但很实用的PHP预定义变量分析
2019/06/25 PHP
做网页的一些技巧
2007/02/01 Javascript
javascript encodeURI和encodeURIComponent的比较
2010/04/03 Javascript
JavaScript中判断页面关闭、页面刷新的实现代码
2014/08/27 Javascript
html的DOM中document对象images集合用法实例
2015/01/21 Javascript
举例说明JavaScript中的实例对象与原型对象
2016/03/11 Javascript
jQuery UI Bootstrap是什么?
2016/06/17 Javascript
Centos7 中 Node.js安装简单方法
2016/11/02 Javascript
微信小程序 特效菜单抽屉效果实例代码
2017/01/11 Javascript
微信小程序 弹框和模态框实现代码
2017/03/10 Javascript
微信小程序表单验证WxValidate的使用
2019/11/27 Javascript
ES2020 新特性(种草)
2020/01/12 Javascript
python简单实现基数排序算法
2015/05/16 Python
Ubuntu 下 vim 搭建python 环境 配置
2017/06/12 Python
python爬取足球直播吧五大联赛积分榜
2018/06/13 Python
Python 实现输入任意多个数,并计算其平均值的例子
2019/07/16 Python
django将网络中的图片,保存成model中的ImageField的实例
2019/08/07 Python
Python 使用matplotlib模块模拟掷骰子
2019/08/08 Python
Python爬虫UA伪装爬取的实例讲解
2021/02/19 Python
Giglio德国网上精品店:奢侈品服装和配件
2016/09/23 全球购物
国际礼品店:GiftsnIdeas
2018/05/03 全球购物
如何强制垃圾回收
2015/10/06 面试题
Python面试题集
2012/03/08 面试题
《回乡偶书》教学反思
2014/04/12 职场文书
初三新学期计划书
2014/05/03 职场文书
学习教师敬业奉献模范事迹材料思想汇报
2014/09/19 职场文书
庆祝新中国成立65周年“向国旗敬礼”网上签名寄语
2014/09/27 职场文书
2014年乡镇卫生院工作总结
2014/11/24 职场文书
2015年体育教学工作总结
2015/05/20 职场文书
Python上下文管理器Content Manager
2021/06/26 Python
SpringBoot详解自定义Stater的应用
2022/07/15 Java/Android