Skip to content

Commit ce87580

Browse files
committed
加载策略 之 按需加载 翻译完毕
1 parent a5c26c1 commit ce87580

File tree

1 file changed

+62
-0
lines changed

1 file changed

+62
-0
lines changed

chapter8.markdown

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -833,6 +833,68 @@ frist_script是页面中一定存在的一个script标签,script是你创建
833833

834834
对很多应用来说,延迟加载的部分大部分情况下会比核心部分要大,因为我们关注的“行为”(比如拖放、XHR、动画)只在用户初始化之后才会发生。
835835

836+
### 按需加载
837+
838+
前面的模式会在页面加载后无条件加载其它的JavaScript,并假设这些代码很可能会被用到。但我们是否可以做得更好,分部分加载,在真正需要使用的时候才加载那一部分?
839+
840+
假设你页面的侧边栏上有一些tabs。点击tab会发出一个XHR请求获取内容,然后更新tab的内容,然后有一个更新的动画。如果这是页面上唯一需要XHR和动画库的地方,而用户又不点击tab的话会怎样?
841+
842+
下面介绍按需加载模式。你可以创建一个require()函数或者方法,它接受一个需要被加载的脚本文件的文件名,还有一个在脚本被加载完毕后执行的回调函数。
843+
844+
require()函数可以被这样使用:
845+
846+
require("extra.js", function () {
847+
functionDefinedInExtraJS();
848+
});
849+
850+
我们来看一下如何实现这样一个函数。加载脚本很简单——你只需要按照动态\<script\>元素模式做就可以了。获知脚本已经加载需要一点点技巧,因为浏览器之间有差异:
851+
852+
function require(file, callback) {
853+
854+
var script = document.getElementsByTagName('script')[0], newjs = document.createElement('script');
855+
856+
// IE
857+
newjs.onreadystatechange = function () {
858+
if (newjs.readyState === 'loaded' || newjs.readyState === 'complete') {
859+
newjs.onreadystatechange = null;
860+
callback();
861+
}
862+
};
863+
864+
// others
865+
newjs.onload = function () {
866+
callback();
867+
};
868+
869+
newjs.src = file;
870+
script.parentNode.insertBefore(newjs, script);
871+
}
872+
873+
这个实现的几点说明:
874+
875+
- 在IE中需要订阅readystatechange事件,然后判断状态是否为“loaded”或者“complete”。其它的浏览器会忽略这里。
876+
- 在Firefox,Safari和Opera中,通过onload属性订阅load事件。
877+
- 这个方法在Safari 2中无效。如果必须要处理这个浏览器,需要设一个定时器,周期性地去检查某个指定的变量(在脚本中定义的)是否有定义。当它变成已定义时,就意味着新的脚本已经被加载并执行。
878+
879+
你可以通过建立一个人为延迟的脚本来测试这个实现(模拟网络延迟),比如ondemand.js.php,如:
880+
881+
<?php
882+
header('Content-Type: application/javascript');
883+
sleep(1);
884+
?>
885+
function extraFunction(logthis) {
886+
console.log('loaded and executed');
887+
console.log(logthis);
888+
}
889+
890+
现在测试require()函数:
891+
892+
require('ondemand.js.php', function () {
893+
extraFunction('loaded from the parent page');
894+
document.body.appendChild(document.createTextNode('done!'));
895+
});
896+
897+
这段代码会在console中打印两条,然后页面中会显示“done!”,你可以在<http://jspatterns.com/book/7/ondemand.html>看到示例。
836898

837899

838900

0 commit comments

Comments
 (0)