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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4595055/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-25 14:15:11  来源:igfitidea点击:

Javascript onload event - how to tell if script is already loaded?

javascriptdynamiconload

提问by

How can I use javascript to determine if an HTMLScriptElement has already been fully loaded?

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

How can I determine if a dynamically loaded script has finished loading withoutusing the onload or onreadystate change events?

如何在使用 onload 或 onreadystate 更改事件的情况下确定动态加载的脚本是否已完成加载?

Code is as follows:

代码如下:

   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; 
      } 

I need help here. I want the callback function to fire even if alreadyAppeneded === trueand the same script was already loaded, but only if that script is completely finished loading.

我在这里需要帮助。即使alreadyAppeneded === true已经加载了相同的脚本,我也希望回调函数触发,但前提是该脚本完全加载完成。

      if (!alreadyAppended || (alreadyAppended && reappend)) { 
         head.appendChild(script); 
      } 
   };

BOTTOM LINE:How do I determine if a script has completed loading? Please ask me questions if needed.

底线:如何确定脚本是否已完成加载?如果需要,请向我提问。

Thank you.

谢谢你。

回答by Stephen

Why not add an id to the script element? Check to see if the id exists before continuing....

为什么不给脚本元素添加一个 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); 
}

回答by LoveAndCoding

Lazy Implementation:Create an array that you can use to push the source of all loaded scripts onto, and as they load, push them onto the list. Each time, check to see if the given src is in the array, and if it is, fire the callback immediately.

延迟实现:创建一个数组,您可以使用该数组将所有已加载脚本的源推送到其中,并在加载时将它们推送到列表中。每次,检查给定的 src 是否在数组中,如果是,立即触发回调。

What you do with the case when its appended, but not loaded becomes the question. If you want the callback to fire, but you want it to fire after it loads, you could do an associative array with a src as the key, and the script element as the value. From there, make the onload or onreadystatechange fire twice by wrapping the original, like so:

当它被附加但未加​​载时,你如何处理它成为问题。如果您希望回调触发,但希望在加载后触发,您可以创建一个关联数组,以 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(); };

You have other code which may need to hook into this, but this should get you started hopefully.

您还有其他代码可能需要与此相关联,但这应该会让您有希望地开始。

回答by JohnO

You can't really tell when a script has loaded. You can put a global variable in the script you want to check and then test for its presence.

您无法真正判断脚本何时加载。您可以在要检查的脚本中放置一个全局变量,然后测试其是否存在。

There is a new project called LABjs (Loading and Blocking Javascript) in order to load scripts dynamically and thus tell when they are actually loaded (http://blog.getify.com/2009/11/labjs-new-hotness-for-script-loading/ <- check it out)

有一个名为 LABjs (Loading and Blocking Javascript) 的新项目,用于动态加载脚本,从而判断它们何时实际加载 (http://blog.getify.com/2009/11/labjs-new-hotness-for-脚本加载/ <-检查一下)