Javascript 是",;异步;如果脚本被动态添加到DOM中,属性/属性是否有用?
这个问题有点像一个相切的问题 我最近看到了一些脚本,它们都是这样做的:Javascript 是",;异步;如果脚本被动态添加到DOM中,属性/属性是否有用?,javascript,asynchronous,pageload,page-load-time,Javascript,Asynchronous,Pageload,Page Load Time,这个问题有点像一个相切的问题 我最近看到了一些脚本,它们都是这样做的: var s = document.createElement('script'); s.type = 'text/javascript'; s.async = true; s.src = 'http://www.example.com/script.js'; document.getElementsByTagName('head')[0].appendChild(s); 这是一种将脚本动态添加到DOM的常用方法,如Stev
var s = document.createElement('script');
s.type = 'text/javascript';
s.async = true;
s.src = 'http://www.example.com/script.js';
document.getElementsByTagName('head')[0].appendChild(s);
这是一种将脚本动态添加到DOM的常用方法,如Steve Souders书中的IIRC所述,“提示所有现代浏览器异步加载脚本(即,不阻止页面呈现或下载后续资产)
如果我在这方面是正确的,那么
s.async=true
语句有什么用处吗?即使对于支持该属性的浏览器来说,这难道不是多余的,因为动态附加的脚本应该已经触发异步下载了吗?我相信你是对的
在中,在将脚本标记附加到head元素之前,他不会设置async属性
我对的理解是,这是一种向浏览器发出信号的方式,表明您不打算通过使用document.write来操纵页面,以便它可以继续呈现而不是停止加载脚本。请参阅的文档,其中包含有关document.write/async问题的更多信息
请注意,使用您的技术时,您不应该使用document.write,因为您无法知道在页面生命周期中脚本将加载到哪里。有趣-我认为我的假设是错误的 基于jQuery开发者论坛中的这条线索: 至少在Firefox中,
async
属性对动态附加的脚本有影响(可能还有Opera,尽管它还不支持该属性)
论坛线程还引用了谷歌的异步跟踪代码实现,虽然它似乎在适当的上下文中使用了async
属性,但实际上似乎语法错误。谷歌使用:
ga.async = true;
当这显然不起作用时;正确的方法是使用以下任一方法:
ga.async = 'async';
或
因此,根据我目前的理解,并非所有浏览器都会在插入DOM后立即执行动态附加的脚本;Firefox(最终还有Opera)需要设置async
属性,以确保这种情况始终发生
有关Firefox实现async
的更多信息,请点击此处:
问题是
s.async=true
是否使用动态插入的脚本,或者这些脚本是否已经异步加载。答案是它们并不是在所有浏览器中异步加载的,正如所解释的(感谢Markus Olsson的链接)
脚本插入脚本在IE和WebKit中异步执行,但在Opera和4.0之前的Firefox中同步执行。在Firefox4.0中,对于脚本创建的脚本,异步DOM属性默认为true,因此默认行为与IE和WebKit的行为相匹配。
在支持async
但尚未默认为异步加载的浏览器中(例如,Firefox 3.6),async=true
起到了作用
(上面的链接确认Gecko 1.9.2(Firefox 3.6使用的布局引擎)支持异步)(现在)指示未插入解析器的脚本元素是异步的;async
属性与插入的非解析器script
元素无关:
第三个是一个标志,指示元素是否将“强制异步”。最初,script
元素必须设置此标志。它由HTML解析器和XML解析器在它们插入的script
元素上取消设置。此外,每当设置了“force async”标志的脚本元素添加了async
内容属性时,该元素的“force async”标志必须取消设置
当然,使用async
content属性意味着脚本将异步执行。spec语言似乎留下了强制同步执行脚本的机会(通过设置属性然后删除它),但实际上这不起作用,可能只是spec中有点模糊。插入的非解析器script
元素是异步的
这个特定的行为是IE和Chrome一直在做的,Firefox已经做了很多年了,现在的Opera也做了(我不知道它是什么时候从上面链接的答案中的旧行为改变过来的)
它很容易测试:
var script = document.createElement("script");
script.src = "script.js";
console.log("a");
document.body.appendChild(script);
console.log("b");
…使用script.js
console.log("script loaded");
…将记录
a
b
script loaded
A.
B
脚本加载
马库斯-伟大的答案,我感谢你的贡献!我进一步研究了这一点,并取得了一些发现——请阅读我刚才添加的答案。jQuery论坛上非常有趣的帖子。我猜我的google fu不够强大,无法找到它;)谢谢我认为这是不对的typeof ga.async
是的“布尔值”
,即使将其设置为'async'
,您也会发现ga.async的值为true
(由于类型强制)。我在FF 3.6中检查了这一点,我相信说它在jQuery中不起作用的人误解了async属性应该做什么,正如其他一些海报所指出的那样。顺便说一句,请注意ga.async=true
会产生类似于
的HTML(至少在Firebug中是这样),但就我所知,重要的是异步属性的存在,而不是它后面的字符串。无论如何,ga.async=“async”
的结果也是一样的。请更正我的上一条评论,显然,如果标记中为async
属性指定了一个值,那么它应该是“async”或空字符串。但是当在DOM中设置它时(如ga.async=
),async是一个布尔值,因此您应该将它设置为true
或false
。正如我所说,ga.async=“async”
产生相同结果的事实只是因为“async”
被强制为true
a
b
script loaded