问题描述
在 IE 中将一个 DOM 或 BOM 对象的原生方法赋给一个变量后,该变量可以成功调用。
造成的影响
在非 IE 浏览器中可能导致脚本异常,停止解析。
受影响的浏览器
IE
问题分析
这里使用 document.getElementById 来说明问题。
在前端开发过程中经常需要使用 document.getElementById 来获取页面中含有 id 属性 DOM 元素,为了方便,该方法经常被简写,如下:
//方式1
var $1 = function(id){return document.getElementById(id);};
//方式2
var $2 = document.getElementById;
用缩写的 $1、$2 测试,代码如下:
var $1 = function(id){return document.getElementById(id);};
var $2 = document.getElementById;
alert($1('d1'));
alert($2('d1'));
各浏览器中表现如下:1
函数名IEFirefox Safari Chrome Opera
$1OKOK
$2OKFAIL
注1:OK 表示可以获取 DIV 元素,FAIL 表示不能获取 DIV 元素,控制台出错。
方式 1 在所有浏览器中均有效,而方式 2 仅在 IE 浏览器中有效。相同的效果也发生在 document 对象的其他方法上, 甚至是 location、history 等 BOM 对象的方法上。如:
//方式1
var println1 = function(str){document.writeln(str);};
//方式2 (仅IE)
var println2 = document.writeln;
//JS
println2('
IE 下方式 2 在 DOM 或 BOM 对象的原生函数赋值给其他变量时会自动将其绑定到在 DOM 或 BOM 对象上, 而非 IE 浏览器(Firefox Safari Chrome Opera)需要用到 this,这里的 this 是 document 对象。 直接调用 $2() 时内部的 this 却是 window 对象,所以造成 $2() 不能根据 id 来正常获取元素。
如果将 document.getElementById 的执行环境换成了 document ,则可以正常的使用 $2 了,如下:
document.getElementById = (function(fn){
return function(){
return fn.apply(document,arguments);
};
})(document.getElementById);
var $2 = document.getElementById;
解决方案
使用方式 1 达到简写一些 DOM 和 BOM 对象原生方法的目的。
更多信息请查看IT技术专栏