我正在尝试在脚本完全加载后执行某些操作。 (IE8)
我用于测试的脚本:http://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js
和无效的:http://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.minaaaaaaaa.js
代码......
var script = create the element and append to head...
// this works fine with FF/Chrome/...
script.onload = function() {alert('script loading complete');}
script.onerror = function() {alert('error loading script');}
// and for IE
script.onreadystatechange = function() {
// this will alert 1.loading 2.loaded
alert(this.readyState);
// this never works
if(this.readyState == 'complete') {alert('script loading complete');}
// this works with either a valid or INVALID url
else if(this.readyState == 'loaded') {alert('script loaded');}
};
在我的情况下,“完整”从不显示,“加载”显示即使网址无效。所以没有办法判断脚本是否在IE下正确加载。
我做错了吗?为什么我永远不会得到完整的状态?
好的,我刚读了一些文章,似乎readystate不是检测脚本加载的可靠方法。
还有另一种方法吗?没有jQuery,但是纯粹的Javascript。
答案 0 :(得分:11)
我发现了一个如何让脚本节点在IE7和IE8中变得“完整”的技巧。以及如何在加载脚本时检测错误何时发生(node.onerror仅在IE9 +中工作)。 黑客入侵
试试吧!
var node = document.createElement('script');
node.src = 'some-[un]existing-url.js';
node.type = 'text/javscript';
node.onreadystatechange = (function(node) {
return function () {
if (/loaded|complete/.test(node.readyState)) {
_finish();
}
};
})(node);
var _finish=function() {
if (node.readyState == 'complete') {
// insert node only after completing the request, though this is not necessary
var head = document.head;
head || (head = document.getElementsByTagName('head')[0]);
head.appendChild(node);
// call success function
_success();
return;
}
var firstState = node.readyState;
// hack: calling 'children' property changes node's readyState from 'loaded' to complete
// (if script was loaded normally) or to 'loading' - if error detected
node.children;
// error detected
if (firstState == 'loaded' && node.readyState == 'loading') {
// custom error code
_error();
}
}
答案 1 :(得分:5)
根据您的评论,以下是如何使用XHR(XMLHttpRequest
)动态添加脚本标记的示意图:
var handleRequest = function( ) { //!! set up the handleRequest callback
if(this.status != undefined) {
/* do something with the status code here */
}
if(this.readyState == 4) {
var script = document.createElement("script") ;
script.setAttribute("type","text/javascript") ;
var text = document.createTextNode(this.responseText) ;
script.appendChild(text) ;
var head = document.getElementsByTagName("head")[0] ;
head.insertBefore(script,head.firstChild) ;
}
} ;
var request ; //!! supposing you have a way to get a working XHR Object
//.. set the XHR Object
request.open("GET",url,true) ;
request.overrideMimeType("text/javascript") ;
request.onreadystatechange = handleRequest ;
request.send(null) ;
请记住,这只是为了让您了解我的意思。从jQuery源代码判断,一个工作示例必须更精细。
链接:
答案 2 :(得分:-1)
检测负载完成
[..] 一个网页建议设置一些在加载完成时调用的事件处理程序。我们通过在前面的代码中添加以下行来实现:
var head= document.getElementsByTagName('head')[0];
var script= document.createElement('script');
script.type= 'text/javascript';
script.onreadystatechange= function () {
if (this.readyState == 'complete') helper();
}
script.onload= helper;
script.src= 'helper.js';
head.appendChild(script);
这里我们在新创建的脚本标记上设置两个不同的事件处理程序。根据浏览器的不同,当脚本加载完毕后,应该调用这两个处理程序中的一个或另一个。 onreadystatechange处理程序仅适用于IE。 onload处理程序适用于Gecko浏览器和Opera。
“this.readyState =='complete'”测试实际上并不完全有效。 readyState理论上经历了一系列状态:
但实际上,州可能会被跳过。根据我使用IE 7的经验,您可以获得已加载的事件或已完成的事件,但不能同时获得这两种事件。
它可能与您是否从缓存加载有关,但似乎有其他因素会影响您获得的事件。有时候我也会收到加载或互动事件,有时候我也没有。测试可能是“this.readyState =='loaded'|| this.readyState =='complete'”,但这可能会触发两次。
http://unixpapa.com/js/dyna.html
<强>更新强>
请你能用这个来阻止你的script.onreadystatechange
回调:
newjs.onreadystatechange = function () {
if (newjs.readyState === 'loaded' || newjs.readyState === 'complete') {
newjs.onreadystatechange = null;
alert('script is complete or loaded.");
}
};
我注意到的另一件事是你正在与==
运算符进行字符串比较。
这可能会产生误导。请改用===
。