关于window.execScript的兼容性问题与解决办法
最先知道的一个是window.eval函数,后来又知道IE下有个window.execScript。其实这两个函数有很大区别的。
先举个例子吧
demo1:
var globalV =123;
function testEval(){
eval(" var globalV = 'global' ");
}
testEval();
alert(globalV); //弹出123,ie与ff都如此
demo2:
var globalV =123;
function testEval(){
execScript(" var globalV = 'global' ");
}
testEval();
alert(globalV); //IE弹出global,ff下没有execScript方法
那么如何解决execScript的兼容性问题呢。今天看了mootools的源码发现了一种比较好的解决办法
var exec=function(text){
if (!text) return text;
if (window.execScript){
window.execScript(text);
} else {
var script = document.createElement('script');
script.setAttribute('type', 'text/javascript');
script.text = text;
document.head.appendChild(script);
document.head.removeChild(script);
}
return text;
}
就是动态插入与删除一段js代码,这样就可以保证代码在全局空间里执行了,这种方法其实之前也在Jquery的源码中见到,实现原理一样
// Evalulates a script in a global context
globalEval: function( data ) {
if ( data && rnotwhite.test(data) ) {
// Inspired by code by Andrea Giammarchi
// http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html
var head = document.head || document.getElementsByTagName( "head" )[0] || document.documentElement,
script = document.createElement( "script" );
if ( jQuery.support.scriptEval() ) {
script.appendChild( document.createTextNode( data ) );
} else {
script.text = data;
}
// Use insertBefore instead of appendChild to circumvent an IE6 bug.
// This arises when a base node is used (#2709).
head.insertBefore( script, head.firstChild );
head.removeChild( script );
}
},
我也想到了一个比较简洁的方法
var exec=function(text){
if(window.execScript){
window.execScript(text);
return text;
}
window.eval.call(window,text);//利用call来改变eval执行的环境,但此方法在ie中无效,不知道为啥
return text;
}
原来eval和window.eval是不同的,惭愧现在才明白
var exec=window.execScript || function(statement) {
// 如果正常浏览器,使用 window.eval
return window.eval(statement);
},