我有一个脚本,知道要加载包含
javascript类的动态脚本.
我正在使用以下代码加载类脚本:
我正在使用以下代码加载类脚本:
var head = document.getElementsByTagName("head")[0]; var script = document.createElement("script"); script.type = "text/javascript"; script.src = "myscript.js"; head.appendChild(script);
然后我尝试使用eval创建新类:
var classObj = eval(" new MyClass()" );
问题是eval的代码正在被执行bofre脚本已经加载到内存中,我收到一个MyClass未定义的错误.
有没有办法同步这些事件?我需要确保脚本完全加载到内存中,然后才能开始分配类.
解决方法
您需要将一个事件处理程序附加到onload方法,符合Web标准的浏览器或onreadystatechange中,检查在Internet Explorer中的script.readyState属性是否等于“已加载”或“完成”.
在通知脚本被加载之前,您可能正在尝试访问尚未声明或创建的对象,函数和属性.
这是一个示例函数,从我的Javascript library,bezen.org中的模块bezen.dom.js中提取:
var appendScript = function(parent,scriptElt,listener) { // append a script element as last child in parent and configure // provided listener function for the script load event // // params: // parent - (DOM element) (!nil) the parent node to append the script to // scriptElt - (DOM element) (!nil) a new script element // listener - (function) (!nil) listener function for script load event // // Notes: // - in IE,the load event is simulated by setting an intermediate // listener to onreadystate which filters events and fires the // callback just once when the state is "loaded" or "complete" // // - Opera supports both readyState and onload,but does not behave in // the exact same way as IE for readyState,e.g. "loaded" may be // reached before the script runs. var safelistener = catchError(listener,'script.onload'); // Opera has readyState too,but does not behave in a consistent way if (scriptElt.readyState && scriptElt.onload!==null) { // IE only (onload===undefined) not Opera (onload===null) scriptElt.onreadystatechange = function() { if ( scriptElt.readyState === "loaded" || scriptElt.readyState === "complete" ) { // Avoid memory leaks (and duplicate call to callback) in IE scriptElt.onreadystatechange = null; safelistener(); } }; } else { // other browsers (DOM Level 0) scriptElt.onload = safelistener; } parent.appendChild( scriptElt ); };
要适应您的需要,您可以将调用替换为catchError,该函数将侦听器包装以捕获和记录错误,并使用修改的函数:
var appendScript = function(parent,e.g. "loaded" may be // reached before the script runs. var safelistener = function(){ try { listener(); } catch(e) { // do something with the error } }; // Opera has readyState too,but does not behave in a consistent way if (scriptElt.readyState && scriptElt.onload!==null) { // IE only (onload===undefined) not Opera (onload===null) scriptElt.onreadystatechange = function() { if ( scriptElt.readyState === "loaded" || scriptElt.readyState === "complete" ) { // Avoid memory leaks (and duplicate call to callback) in IE scriptElt.onreadystatechange = null; safelistener(); } }; } else { // other browsers (DOM Level 0) scriptElt.onload = safelistener; } parent.appendChild( scriptElt ); };