Javascript onload事件 - 如何判断脚本是否已加载?

6

如何使用JavaScript确定HTMLScriptElement是否已完全加载?

如何确定动态加载的脚本是否已完成加载,而不使用onload或onreadystate事件?

代码如下:

   TOOL.loadScript = function (url, callback, reappend, deepSearch) {
      var head, curr, child, tempScript, alreadyAppended, queue, 
      alreadyHandled, script, handler, loadFunc; 

      head = document.getElementsByTagName("head")[0];
      tempScript = document.createElement("script");
      tempScript.src = url;
      alreadyAppended = false;

      queue = []; 

      if (deepSearch) {
         // search entire document
         queue.push(document.firstElementChild);
      }
      else { 
         // just search the head element
         queue.push(head); 
      }

      while (queue.length !== 0) { 
         curr = queue.shift();

         // add child nodes to queue
         child = curr.firstElementChild; 
         if (child !== null && child !== undefined) { 
            queue.push(child);
            child = child.nextElementSibling;
            while (child !== null && child !== undefined) { 
               queue.push(child);
               child = child.nextElementSibling;
            } 
         }

         if (curr.tagName !== null && curr.tagName !== undefined) {
            if (curr.tagName.toLowerCase() === "script" && curr.src === tempScript.src) {
               script = curr;
               alreadyAppended = true;
               break;
            }
         }
      }

      if (!alreadyAppended) { 
         script = document.createElement("script");
         script.type = "text/javascript"; 
         script.async = true; 
         script.src = url; 
      } 

      alreadyHandled = false; 

      handler = function (event) {
         console.log("handling event..."); 
         if (!alreadyHandled) { 
            if ((!event.readyState) || (event && (event.readyState === "loaded" || event.readyState === "complete"))) {  
               alreadyHandled = true; 
               callback.apply(script, [url]);
               if (loadFunc) { 
                  loadFunc.apply(script, arguments); 
               }
            }
         }
      }; 

      if (script.onreadystatechange === undefined) { 
         loadFunc = script.onload;
         script.onload = handler; 
      } 
      else { 
         loadFunc = script.onreadystatechange; 
         script.onreadystatechange = handler; 
      } 

我需要帮助。即使alreadyAppeneded === true并且相同的脚本已经加载,我也希望回调函数能够触发,但只有在该脚本完全加载完成后才能触发。

      if (!alreadyAppended || (alreadyAppended && reappend)) { 
         head.appendChild(script); 
      } 
   };
底线:我如何确定脚本是否已加载完成?如果需要,请向我提问。
谢谢。
3个回答

3
为什么不在脚本元素中添加一个ID?在继续之前检查该ID是否存在...
function includeJs(jsFilePath) {

  if (document.getElementById(jsFilePath+"_script")) {
    return;
  }
  var js = document.createElement("script");

  js.type = "text/javascript";
  js.id = jsFilePath+"_script";
  js.src = jsFilePath;

  document.body.appendChild(js); 
}

4
注意:这并不验证任何东西是否已加载,只是确认元素已被创建。 - Stephen
谢谢你提醒我这个可能性。我一直在尝试解决同一页上重复插入脚本的问题,现在终于解决了。要是我早 6 小时看到这个就好了 :D - Leniel Maccaferri

2
懒加载实现:创建一个数组,用于将所有已加载脚本的源推入其中,并在它们加载时将它们推入该列表。每次检查给定的src是否在数组中,如果是,则立即触发回调函数。
当附加但未加载时,你需要考虑如何处理此情况。如果你想要回调函数在加载后触发,可以使用具有src作为键和脚本元素作为值的关联数组。从那里开始,通过包装原始的onload或onreadystatechange使其触发两次,例如:
var temponload = element.onreadystatechange || element.onload;
if (element.onreadystatechange === undefined)
    element.onload = function(e) { temponload(); temponload(); };
else
    element.onreadystatechange = function (e) { temponload(); temponload(); };

你还有其他可能需要连接到此代码的代码,但希望这可以让你开始。

1

你无法确切地知道脚本何时加载完成。你可以在要检查的脚本中放置一个全局变量,然后测试其是否存在。

现在有一个名为LABjs(加载和阻止Javascript)的新项目,可以动态加载脚本,从而告诉您它们实际上何时加载完成(http://blog.getify.com/2009/11/labjs-new-hotness-for-script-loading/ <- 去看看吧)


如果在脚本中设置了一个变量,你就可以知道该脚本已经被加载。 - user985399

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接