简体   繁体   English

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

[英]How to detect whether your Javascript is being included synchronously or asynchronously

I am trying to detect whether the current Javascript file that's being executed is included synchronously (via a regular script tag) 我试图检测当前正在执行的Javascript文件是否同步包含(通过常规脚本标记)

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

or asynchronously via inserting a script element into the DOM programatically, something like 或者通过以编程方式将脚本元素插入DOM来异步,例如

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

and consequently whether document.write can be used or not. 因此是否可以使用document.write I've figured out a crazy solution which tests whether document.write works, see this gist . 我已经找到了一个疯狂的解决方案来测试document.write是否有效,看看这个要点

Basically, it works by using document.write to write out an element - I chose an empty script tag. 基本上,它通过使用document.write写出一个元素 - 我选择了一个空的脚本标记。 Then it queries the DOM to determine whether that script element was successfully written out. 然后它查询DOM以确定是否已成功写出该脚本元素。 If it was - the script must have be included synchronously, if it wasn't - it was included asynchronously. 如果是 - 脚本必须同步包含,如果不是 - 它是异步包含的。

This solution works in all browsers I've tested so far (all major ones including IE7+) except for Opera. 这个解决方案适用于我迄今为止测试的所有浏览器(包括IE7 +在内的所有主要浏览器),但Opera除外。

The question is: is there a better solution? 问题是:有更好的解决方案吗?

Note: I have also tried checking document.readyState , but that does not appear to be helpful in IE. 注意:我也尝试检查document.readyState ,但这似乎对IE没有帮助。

Also note: I don't need a lecture that document.write is evil. 还要注意:我不需要一个document.write是邪恶的讲座。 I know. 我知道。

Update: turns out that in addition to not working on Opera, my technique is also unreliable in certain cases in IE and other browsers - document.write may or may not work depending on timing or caching scenario. 更新:事实证明,除了不使用Opera之外,我的技术在IE和其他浏览器的某些情况下也是不可靠的 - 根据时间或缓存方案, document.write可能会也可能不会工作。 The spec seems to say as much. 规范似乎也是如此。

this is evil but you could redefine the document functions and write your own. 这是邪恶的,但你可以重新定义文档功能并编写自己的文档。 something like this perhaps: 也许这样的事情:

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

of course you would need to handle all the different browser quirks and and all the different ways one could add a script element to the page, but it is an alternative to what you describe 当然,您需要处理所有不同的浏览器怪癖以及可以向页面添加脚本元素的所有不同方式,但它可以替代您描述的内容

If you have full control over all sides, you can use a dynamic server page for the JS and query parameters to the url as needed and then use that to set a variable inside the script. 如果您可以完全控制所有方面,则可以根据需要使用JS的动态服务器页面和URL的查询参数,然后使用它在脚本中设置变量。

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

Might be possible to do this all client side by checking "src" attribute of the script element, but I'm not positive on that. 可能通过检查脚本元素的“src”属性来做所有客户端,但我不是肯定的。

Well, here is a quick and dirty solution. 嗯,这是一个快速而肮脏的解决方案。 We assume that if the DOMContentLoaded event has fired, the entire document including all scripts have been loaded. 我们假设如果已触发DOMContentLoaded事件,则已加载包含所有脚本的整个文档。 If your script is executed before that, it has been executed sort-of ' synchroneously ' by your definition. 如果您的脚本在此之前执行,则它已按您的定义“ 同步 ”排序。 If it is executed afterwards, it has to be loaded through another way (' asynchroneously '). 如果之后执行,则必须通过另一种方式加载(' asynchroneously ')。

Again, quick and dirty: In your html file create a script tag in your head; 再次,快速和肮脏:在你的html文件中创建一个脚本标记; To be cross-browser compatible, I believe it has to be the first script tag in your html file (note: window.DOMready is falsey if undefined in modern browsers). 要进行跨浏览器兼容,我相信它必须是你的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>

Then, in your script files you can check for the window.DOMready property. 然后,在脚本文件中,您可以检查window.DOMready属性。 If true, your script has been loaded asynchroneously. 如果为true,则表示您的脚本已异步加载。 Example: 例:

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

Enjoy! 请享用!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM