各浏览器对document.getElementById等方法的实现差异
所有Web前端同仁对 document.getElementById 都非常熟悉了。开发过程中经常需要用其获取页面id为xx的元素,自从元老级JS库Prototype流行后,都喜欢这么简写它
1 2 | // 方式1 function $(id){ return document.getElementById(id); } |
有没有人想过为什么要这么写,而不用下面的方式写呢?
1 2 | // 方式2 var $ = 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,以下是个简单示例
1 2 3 4 5 6 7 8 9 | // 定义一个函数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,则可以正常的使用$了。如下
1 2 3 4 5 6 7 8 9 | // 修复document.getElementById document.getElementById = ( function (fn){ return function (){ return fn.apply(document,arguments); }; })(document.getElementById); // 修复后赋值给$,$可正常使用了 var $ = document.getElementById; |
再次,ECMAScript5 中为function新增的 bind 方法可以实现同样的效果
1 2 | // 方式3 var $ = document.getElementById.bind(document); |
但目前方式3只有IE9/Firefox/Chrome/支持。
分析了getElementById的情况,下面的一些方法在各浏览器中的差异原因就很好明白了
1 2 3 4 5 6 7 8 9 10 11 | 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可运行,其它浏览器报错 |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 周边上新:园子的第一款马克杯温暖上架
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
· 使用C#创建一个MCP客户端