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

时间:2011-12-23 16:39:37

标签: 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
}

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

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

4 个答案:

答案 0 :(得分:37)

如果脚本以正常的同步方式加载,那么只需确保 <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);
}

并像这样使用它:

whenAvailable("twttr", function(t) {
    // do something
});

whenAvailable的第二个参数中给出的函数在全局twttr对象上定义window之前不会执行。你可以为FB做同样的事情。

重要说明:这些库可能还提供了一些内置的方法来在加载后执行代码。你应该在各自的文档中寻找这样的钩子。

答案 1 :(得分: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);
});

答案 2 :(得分:1)

如果Facebook脚本是异步加载的,那么Facebook有一种支持的方式来在库加载时执行代码,这应该比轮询它更有效。请参阅此答案以获取示例:https://stackoverflow.com/a/5336483/816620

如果同步加载Facebook脚本,则不必等待它们 - 它们将在运行之后的任何其他脚本之前加载。

答案 3 :(得分:0)

const checkIfLoaded = ('lib', cb) => {
  const interval = setInterval(() => {
    if (lib) {
      typeof cb === 'function' && cb();
      clearInterval(interval);
    } else {
      console.log('not yet');
    }
  }, 100);
}