IEfans/IE专区/IE相关/内容

在IE浏览器中模拟Worker

IE相关 2010-08-08 12:42 阅读(2789)
在IE8下的eval是不支持下面两种的用法的,很杯具,都会提示“对象不支持此属性或方法”的错误。说到这个,还发现一点很容易造成失误的地方:在浏览器解析过的script中的代码,浏览器不会重新对该script标签内的行内脚本、外联脚本执行,就算是重新给script标签定义行内脚本或者修改它的src来链接到其他的javascript脚本,浏览器都不会重新解析。 //第一: eval("onmessage=function(str){alert(str);}"); onmessage("shllo"); //第二: var s = document.createElement("script"),h=document.getElementsByTagName("head")[0]; s.text="onmessage=function(str){alert(str);}"; h.appendChild(s); onmessage("hello"); ——————- 提IE8 eval的兼容性分界线 ——————– 从上一篇文章《Web Worker浅析》中,我们了解到Worker的思维是跟Ajax类似的,包括它也不支持跨域调用javascript文件,这说明底层的数据交互还是跟Ajax的模式类似(也有可能就是使用了Ajax的方式)。但是由于IE8及以下版本都不支持Worker,所以IE就不能充分利用Worker的优点来优化浏览器执行javascript代码的性能了。但是既然Worker跟Ajax类似,那么就让IE浏览器使用Ajax的方式来实现吧,这也不是不行的。 在IE浏览器中实现Worker机制,一个比较棘手的问题是postMessage、onmessage在主页面和Worker之间的调用问题,从代码上看,主页面是通过Worker类的实例化对象来调用postMessage、onmessage,而Worker里是直接声明和调用。所以在IE里,就可以模拟Worker的操作方式了。下面是我在IE下实现的方式: 在IE下重新定义Worker类,并且带有一个postMessage方法,这样就的话不会跟支持Worker的浏览器相冲突 使用Ajax的方式来加载外联的javascript文件,并通过eval执行返回的代码 通过一个全局的字面量对象,来实现两个文件之间的数据传输 不能改变标准的Worker类的编写方式,这个是一定要做到的 从上面的几点思路出发,编写了下面的实现代码: (function(g){ if(!document.all) return; var xhr=function(){ var x = null; try{ x = new ActiveXObject("Msxml2.XMLHTTP"); }catch(e){ x = new ActiveXObject("Microsoft.XMLHTTP"); } return x; } g.postMessage = function(data){ g._evt_.data = data; } var Worker = function(url){ this.url = url; } Worker.prototype={ postMessage:function(data){ g._evt_={}; g._evt_.data=data; var x=xhr(),t=this; x.open("GET",this.url,true); x.onreadystatechange=function(){ if(x.readyState === 4 && (x.status === 304 || x.status === 200)){ //直接使用eval(x.responseText)在IE8下会提示错误,很奇怪,可能跟eval函数有关了 //为此不得不使用这种不太牢固的方法 eval(x.responseText.replace("onmessage","var onmessage")); onmessage(g._evt_); //执行Worker中定义的onmessage方法 t.onmessage(g._evt_); //执行主页面中的onmessage方法 g._evt_ = null; } } x.send(); } } g.Worker = Worker; })(this); 在使用上有一点得注意,虽然在代码上没改变,但是在主页面中postMessage和onmessage的顺序得保持:先写onmessage、接着写postMessage方法,主要是为了在IE下能兼容。比如: var worker = new Worker("ieworker.js"); worker.onmessage = function(evt){ alert(evt.data); } //注意postMessage方法一定要在onmessage后面声明,否则会导致代码只会有一次有效。 worker.postMessage("supersha"); 到目前为止,测试还算良好,《测试页面》,在各个浏览器下都能够跑起来。 目前这个只是个简单的实现方案,代码上还是比较简单的,有待进一步的完善…… via:ilovejs
相关应用
必备软件
相关阅读