使用document.write是跨浏览器跨域同步加载脚本的唯一可能方式
Is using document.write the only possible way to load a script synchronously cross browser cross domain?
我想模仿这种行为:
<script src="console.log.1.js"></script>
<script>console.log(2)</script>
<script>console.log(3)</script>
退出:
1
2
3
这样做不起作用:
<script>
var x = document.createElement("script");
x.src = "console.log.1.js";
x.async = false;
x.defer = false;
document.body.appendChild(x);
console.log("2");
console.log("3");
</script>
它注销:
2
3
1
到目前为止,我找到的唯一方法是:
<script>
document.write("<scrip" + "t src='console.log.1.js'></scrip" + "t>");
</script>
<script>
console.log("2");
console.log("3");
</script>
这真的是在所有浏览器中强制同步加载外部脚本的唯一方法吗?为什么设置async=false,defer=false无效?
更新
仅供参考,如果有人想知道,以下文档.write初始工作(在Chrome中):
<script>
// http://jsbin.com/avatiw logs "during"
document.write('<scrip' + 't>console.log("before");document.write("<scrip" + "t src=''"http://jsbin.com/avatiw''"></scrip" + "t>");</scrip' + 't>');
document.write('<scrip' + 't>console.log("after");</scrip' + 't>');
</script>
工作和注销:
"before"
"during"
"after"
是的,这是在页面解析期间强制加载脚本的唯一方法。或者至少,我愿意相信的唯一方法是跨浏览器运行良好。
如果你的剧本是这样的,我可以看到你的想法:
<script>
var x = document.createElement("script");
x.src = "console.log.1.js";
x.async = false;
x.defer = false;
document.body.appendChild(x);
</script>
<script><!-- note the new script element -->
console.log("2");
console.log("3");
</script>
因为理论上,当解析器命中script
元素时,它会挂起所有内容(因为可能存在document.write
语句)并调用JavaScript层。因此,您可能会认为,在body
的末尾添加一个script
元素会将其插入两者之间。
但是,通过appendChild
添加script
元素是根本不同的,它本质上是一种异步操作(在下载脚本时,您的代码会继续,而标记中的script
元素除了defer
或async
属性外,情况并非如此)。我无法指出任何一个规范来说明原因,但你看到的行为正是我所期望的。与标记内联的script
元素的处理有点特殊。
我们可以看出,问题出在下载上—至少在Chrome中—通过将结果与使用具有内联内容的CCD_ 11元素进行比较。
使用外部文件(实时副本|实时源):
<script>
console.log("before");
(function() {
var s = document.createElement("script");
s.src = "http://jsbin.com/avatiw"; // Logs the word "during"
document.body.appendChild(s);
})();
</script>
<script>
console.log("after");
</script>
结果:
之前之后在期间
使用内联脚本(实时副本|实时源代码—请注意,我没有尝试制作这种跨浏览器,它在Chrome和Firefox中工作,因为它们支持script
元素上的text
属性):
<script>
console.log("before");
(function() {
var s = document.createElement("script");
s.text = "console.log('during');";
document.body.appendChild(s);
})();
</script>
<script>
console.log("after");
</script>
输出:
之前在期间在
我实际上发现使用LazyLoad插件非常适合这个用例,即
if (typeof jQuery === 'undefined')
LazyLoad.js('//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js', function() {
initialize();
});
else
initialize();
相关文章:
- 当包含另一个asp文件时,是否也包含所有引用的样式和脚本页面
- 借助asp.net验证或java脚本对多个文本进行验证
- chrome扩展:尽管运行了at:documentidle,js脚本还是过早启动
- Java脚本时间添加
- 不显示带有本地json文件数据的谷歌地图脚本
- JQuery添加元素需要在我的js之前再次添加JQuery脚本
- 从远程脚本获取用户IP
- 如何在 Google 应用脚本中 sendEmail 函数的范围内的唯一非空白列中返回值
- Java 脚本为每个映像创建唯一的类
- 如何停止 PHP 脚本的响应消息显示为页面的唯一内容
- Google 应用脚本:返回 2 个两个范围之间唯一值的函数
- Spotfire Java脚本将字段拆分为唯一值,并每30秒更新一次MapChart可视化,以反映值的变化
- 使用document.write是跨浏览器跨域同步加载脚本的唯一可能方式
- 将唯一ID传递给AJAX脚本
- jQuery UI选项卡示例-打开新选项卡=为每个选项卡添加唯一的脚本
- 有没有一种方法可以为我的Chrome扩展唯一标识内容脚本运行的iframe
- 分配,在主索引页上为脚本使用唯一的Wordpress帖子id
- 将脚本应用于具有唯一id的多个视频标签's
- Jquery翻转脚本的背面没有显示唯一的内容
- 为什么我的重复删除脚本没有捕获唯一值