我有一个问题。我的一个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
}
但是这显然不起作用,因为它一直高速发射超时并且页面挂起。
请帮助我,因为这个问题我无法入睡。
答案 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
会立即返回,如果您想等待定义某个变量,请使用以下内容。
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);
}