如何检测您的Javascript是同步还是异步包含

时间:2012-02-23 04:32:11

标签: javascript

我正在尝试检测当前正在执行的Javascript文件是否同步包含(通过常规脚本标记)

<script src="myscript.js"></script>

或异步通过以编程方式将脚本元素插入DOM,如

var script = document.createElement('script')
script.src = 'myscript.js'
document.body.appendChild(script)

因此是否可以使用document.write。我已经找到了一个疯狂的解决方案来测试document.write是否有效,请参阅this gist

基本上,它通过使用document.write来写出一个元素 - 我选择了一个空的脚本标记。然后它查询DOM以确定是否已成功写出该脚本元素。如果是 - 脚本必须同步包含,如果它不是 - 它是异步包含的。

此解决方案适用于我迄今为止测试的所有浏览器(包括IE7 +在内的所有主要浏览器),但Opera除外。

问题是:有更好的解决方案吗?

注意:我也尝试过检查document.readyState,但这似乎对IE没有帮助。

还要注意:我不需要document.write是邪恶的讲座。我知道。

更新:事实证明,除了不使用Opera之外,我的技术在IE和其他浏览器的某些情况下也是不可靠的 - document.write可能会或可能不会起作用,具体取决于时间或缓存方案。 spec似乎也是这么说的。

3 个答案:

答案 0 :(得分:1)

这很邪恶,但您可以重新定义文档功能并编写自己的文档功能。也许是这样的事情:

var oldAppendChild = document.body.appendChild;

document.body.appendChild = function(child) {
    //examine if child is a script element, do stuff with it if it is
    //finally do what the original function did and:
    oldAppendChild(child);
}

当然,您需要处理所有不同的浏览器怪癖以及可以向页面添加脚本元素的所有不同方式,但它可以替代您描述的内容

答案 1 :(得分:1)

如果您可以完全控制所有方面,则可以根据需要使用JS的动态服务器页面和URL的查询参数,然后使用它在脚本中设置变量。

var script = document.createElement('script');
script.src = 'myscript.php?type=asynch';
document.body.appendChild(script);

通过检查脚本元素的“src”属性,可以在所有客户端执行此操作,但我对此并不乐观。

答案 2 :(得分:0)

嗯,这是一个快速而肮脏的解决方案。我们假设如果已触发DOMContentLoaded事件,则已加载包含所有脚本的整个文档。如果您的脚本在此之前执行,则它已根据您的定义按“同步”排序。如果之后执行,则必须通过其他方式加载(' asynchroneously ')。

再次,快速和肮脏:在你的html文件中创建一个脚本标记;为了跨浏览器兼容,我认为它必须是你的html文件中的第一个脚本标记(注意:如果在现代浏览器中未定义,window.DOMready是假的)。

<script>
// this property by default is false
window.DOMready = false;

// all browsers but IE<8
// wait for the DOMContentLoaded event and set window.DOMready to true
if (document.addEventListener) {
    document.addEventListener("DOMContentLoaded", function () {
        window.DOMready = true;
    }, false);

} else {
    // not entirely accurate but functioning in IE<8
    // you may want to use another IE solution if you care
    window.onload = function () {
        window.DOMready = true;
    }
}
</script>

然后,在脚本文件中,您可以检查window.DOMready属性。如果为true,则表示您的脚本已异步加载。例如:

// myscript.js
if (window.DOMready) {
    // we have been loaded asynchroneously
} else {
    // we have been loaded synchroneously
}

享受!