如何等待另一个JS加载进行操作?

mvb*_*fst 22 javascript

我有一个问题.我的一个JS脚本需要首先加载Facebook SDK和Twitter小部件JS.Facebook创建FB对象,Twitter创建twttr对象.它们都会在我的脚本触发后创建这些对象,即使它们是从中加载的<head>.

我认为解决方案是定期检查是否定义了FB和twttr,然后继续执行我的脚本.但我不知道该怎么做.

我尝试创建一个循环

while (typeof FB === 'undefined' || typeof twttr === 'undefined' || typeof twttr.widgets === 'undefined') {
    // run timeout for 100 ms with noop inside
}
Run Code Online (Sandbox Code Playgroud)

但这显然不起作用,因为它一直高速发射超时并且页面挂起.

请帮助我,因为这个问题我无法入睡.

Way*_*ett 40

如果脚本在正常,装同步的方法,那么只要确保你的 <script>包括出现后,在文档库中的脚本<head>.另一方面,如果这些脚本异步加载对象(看起来就像这样),那么创建如下内容:

function whenAvailable(name, callback) {
    var interval = 10; // ms
    window.setTimeout(function() {
        if (window[name]) {
            callback(window[name]);
        } else {
            window.setTimeout(arguments.callee, interval);
        }
    }, interval);
}
Run Code Online (Sandbox Code Playgroud)

并像这样使用它:

whenAvailable("twttr", function(t) {
    // do something
});
Run Code Online (Sandbox Code Playgroud)

第二个参数中给出的函数whenAvailabletwttr在全局window对象上定义后才会执行.你可以做同样的事情FB.

重要说明:这些库可能还提供了一些在加载执行代码的内置方法.您应该在各自的文档中查找此类挂钩.

  • 而是使用`window.setInteval`和`window.clearInterval`而不是`window.setTimeout`和递归:https://jsfiddle.net/2bubub2j/因为如果你选择`use strict`那你就会遇到问题参数对象. (3认同)
  • 非常感谢。我使用了您的函数,但必须将条件修改为“if (typeof eval(name) !== 'undefined')”,因为它不适用于诸如 'twttr.widgets' 之类的名称 (2认同)

Fil*_*efp 5

你是否在页面加载时执行脚本?(即body onload="do_this ();")

这应该使您的代码在加载所有外部资源后执行.


关于setTimeout的使用

setTimeout 将立即返回,如果您想等待定义某个变量,请使用如下所示的内容.

function when_external_loaded (callback) {
  if (typeof FB === 'undefined' || typeof twtter === 'undefined') {
    setTimeout (function () {
       when_external_loaded (callback);
    }, 100); // wait 100 ms
  } else { callback (); }
}

...

when_external_loaded (function () {
    alert (FB);
    alert (twtter);
});
Run Code Online (Sandbox Code Playgroud)