标准参考
无。
问题描述
页面开发过程中,为了避免页面加载时引入过多外部 JS 文件,导致阻塞页面内容下载及渲染的情况出现。将会采用页面内容加载完成后,动态加载外部 JavaScript 文件的方法来解决此类问题。但是,需要注意的是,常用动态插入外部脚本文件的方法在各浏览器中的执行顺序并不一致。
造成的影响
对于动态插入的 SCRIPT 文件,不能保证在各浏览器能阻塞其后脚本的执行。
受影响的浏览器所有浏览器
问题分析
使用 appenChild insertBefore 等方法向文档中动态插入 SCRIPT 节点后,各浏览器中对脚本的执行顺序存在差异。
以下例子中均使用脚本代码插入远程文件:http://code.jquery.com /jquery-1.4.2.js ( jQuery 源码 ),该文件中定义了全局变量 $,当远程脚本文件加载完成后该变量将可用 。
情况1:
<script>
var js = document.createElement("script");
document.getElementsByTagName("head")[0].appendChild(js);
js.src = 'http://code.jquery.com/jquery-1.4.2.js';
</script>
<script type="text/javascript">
alert($)
</script>
代码首先创建 SCRIPT 标记并插入到 HEAD 标记中,再将 SCRIPT 的 src 属性指向外部 JS 文件,由之后的 SCRIPT 标记中代码调用外部程序全局变量。
各浏览器表现及分析如下:IE Firefox Opera 弹出($)函数体。此方法中动态附加进文档的 js 文件会阻断下一个 SCRIPT 标记内的代码解析,直至它全部解析完。
Chrome Safari 脚本出错,"$ is not defined"。此方法中动态附加进文档的 js 文件不会阻断下一个 SCRIPT 标记内的代码解析。
情况2:
<script type="text/javascript">
var js = document.createElement("script");
js.src = 'http://code.jquery.com/jquery-1.4.2.js';
document.getElementsByTagName("head")[0].appendChild(js);
</script>
<script type="text/javascript">
alert($)
</script>
代码首先创建 SCRIPT 标记,将 src 属性指向外部 JS 文件。最后插入到 HEAD 标记中,由之后的 SCRIPT 标记中代码调用外部程序全局变量。
各浏览器表现及分析如下: Firefox Opera 弹出($)函数体。此方法中动态附加进文档的 js 文件会阻断下一个 SCRIPT 标记内的代码解析,直至它全部解析完。
IE Chrome Safari 脚本出错,"$ is not defined"。此方法中动态附加进文档的 js 文件不会阻断下一个 SCRIPT 标记内的代码解析。
情况3:
<script type="text/javascript">
var js = document.createElement("script");
document.getElementsByTagName("head")[0].appendChild(js);
js.src = 'http://code.jquery.com/jquery-1.4.2.js';
alert($)
</script>
代码首先创建 SCRIPT 标记,将 src 属性指向外部 JS 文件。最后插入到 HEAD 标记中,其后代码立即调用外部程序全局变量。
各浏览器表现及分析如下: 所有浏览器 脚本出错,"$ is not defined"。此方法中动态附加进文档的 js 文件不会阻断同一个 SCRIPT 标记内的代码解析。
情况4:
<script id="a"></script>
<script type="text/javascript">
var a=document.getElementById('a');
a.src = 'http://code.jquery.com/jquery-1.4.2.js';
alert($)
</script>
代码获取某个 SCRIPT 标记的引用,在将其 src 属性指向外部 JS 文件,其后代码立即调用外部程序全局变量。
各浏览器表现及分析如下: 所有浏览器 脚本出错,"$ is not defined"。此方法中动态附加进文档的 js 文件不会阻断同一个 SCRIPT 标记内的代码解析。
情况5:
<script id="a" ></script>
<script type="text/javascript">
var a=document.getElementById('a');
a.src = 'http://code.jquery.com/jquery-1.4.2.js';
</script>
<script type="text/javascript">
alert($)
</script>
代码获取某个 SCRIPT 标记的引用,在将其 src 属性值变更为外部 JS 文件,由之后的 SCRIPT 标记中代码调用外部程序全局变量。
各浏览器表现及分析如下:IE Firefox Opera 弹出($)函数体。此方法中动态附加进文档的 js 文件会阻断下一个 SCRIPT 标记内的代码解析,直至它全部解析完。
Chrome Safari 脚本出错,"$ is not defined"。此方法中动态附加进文档的 js 文件不会阻断下一个 SCRIPT 标记内的代码解析。
综合以上情况,对于动态插入的 SCRIPT 文件,使用不同的插入方法将有不同的表现,不能保证在各浏览器能阻塞其后脚本的执行。
解决方案
对于必须动态附加到文档的外部 js 文件,要保证动态引入的脚本全部执行完成后,才能执行后续代码。
可以将此部分代码封装后调用,如:
function loadJS(url, success) {
var domScript = document.createElement('script');
domScript.src = url;
success = success || function(){};
domScript.onload = domScript.onreadystatechange = function() {
if (!this.readyState || 'loaded' === this.readyState || 'complete' === this.readyState) {
success();
this.onload = this.onreadystatechange = null;
this.parentNode.removeChild(this);
}
}
document.getElementsByTagName('head')[0].appendChild(domScript);
}
//执行加载外部 JS 文件
loadJS('a.js',function (){
loadJS('b.js',function (){
loadJS('c.js',function (){
alert('ok');
});
});
});
分享到:
相关推荐
支持BX-5E1,BX-5E2,BX-5E3
个人整理BX-5E动态库调用说明文档,希望对二次开发的朋友有点用。
BlueX发行CEVA蓝牙低功耗IP,用于BX2400可穿戴SoC 这个链接很重要->https://bxble-sdk-doc.readthedocs.io/zh_CN/latest/ Ultra-low power BX2400 IC winning global OEM customers including Huami SHANGHAI, June ...
该代码开发环境为PB8.0 实现了向仰邦BX_5K2控制卡发送动态文字 支持屏幕分辨率为64*96,可以自动换行
(1) 根据下述情况,分别编写程序,记录 BX 中 1 的个数(需要考虑 BX 中二进制 串的特殊情况),要求如下: 循环次数已知 循环次数未知 (2) 按照下列要求,编写相应程序段。 1) 起始地址为 string 的主存...
LED控制 BX 5UT
OLYMPUS BX51显微镜中文操作说明书
BX-5U1 BX-5U2 BX-5U3等系列单色/多色显示屏控制软件BX-5U1 BX-5U2 BX-5U3等系列单色/多色显示屏控制软件
仰邦BX-5M、BX-6 C# SDK。文档和Demo都有,方便开发人员使用。
用Java编写程序,求一元二次方程ax²+bx+c=0的根(系数在程序中给定),并输出。
XX科技有限公司 XX科技有限公司 文件名称 文件编号编码原则 文件版本 A 文件编号 HRD-03-QP-001 页 次 1/4 制订部门 研发部 制订日期 2011年04月23日 生效日期 2011-04-26 文件名称: 文件编号编码原则 文件版本:A ...
BX-4M1 LED控制卡驱动 BX-4M1 LED控制卡驱动BX-4M1 LED控制卡驱动BX-4M1 LED控制卡驱动
EU-BX字体
苏州中振汽车零部件有限公司 文件名称 文件编号编码原则 文件版本 A 文件编号 HRD-03-QP-001 页 次 1/4 制订部门 品质部 制订日期 2011年10月15日 生效日期 2011-10-17 文件名称: 文件编号编码原则 文件版本:A ...
BlueX发行CEVA蓝牙低功耗IP,用于BX2400可穿戴SoC 这个链接很重要->https://bxble-sdk-doc.readthedocs.io/zh_CN/latest/ Ultra-low power BX2400 IC winning global OEM customers including Huami SHANGHAI, June ...
此目录中的文件被视为而不是React页面。学到更多要了解有关Next.js的更多信息,请查看以下资源: -了解Next.js功能和API。 交互式Next.js教程。 您可以查看-欢迎您提供反馈和意见!在Vercel上部署部署Next.js应用...
es,bx地址跳到指定位置单顺序跳出流程指令.rar...............................
LED俄二次开发文档,BX-5E系列产品用户手册
校准浏览器 浏览器。 我看了一下谷歌的obj-c客户端,对我来说有几个问题: Bootstrapping 在随机文档和代码之间切换需要超过五分钟的时间。 我不想与所有 API 集成,只想与日历集成。 将整个客户拉入其中的一部分...