我有一个脚本,它知道动态加载包含 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 的代码,并且我收到一条错误,指出 MyClass 未定义。
有办法同步这些事件吗?我需要确保脚本已完全加载到内存中,然后才能开始从中分配类。
最佳答案
您需要将事件处理程序附加到 onload 方法(在符合 Web 标准的浏览器中)或 onreadystatechange,在 Internet Explorer 中检查 script.readyState 属性是否等于“已加载”或“完成”。
在收到脚本已加载的通知之前,您可能正在尝试访问尚未声明或创建的对象、函数和属性。
这是一个示例函数,从模块 bezen.dom.js 中提取在我的Javascript library, bezen.org :
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, 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 = 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 );
};
关于javascript - 动态脚本加载同步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2321204/