Content Table

动态加载 JS 和 CSS

动态加载 JS 文件的正确姿势中列举了多种加载 JS 的方式,下面摘出个人最喜欢的方式,用于动态加载 JS 和 CSS。

动态加载 JS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<title>Load JS</title>
</head>

<body>
<script>
/**
* 使用 Promise 异步加载 JS
*
* @param {String} url JS 的路径
* @param {String} id JS 的 <style> 的 ID,如果已经存在则不再重复加载,默认为时间戳+随机数
* @return 返回 Promise 对象, then 的参数为加载成功的信息,无多大意义
*/
function loadJs(url, id = Date.now() + '-' + Math.random()) {
return new Promise(function(resolve, reject) {
// 避免重复加载
if (document.getElementById(id)) {
resolve('success: ' + url);
return;
}

var script = document.createElement('script');

if (script.readyState) { // IE
script.onreadystatechange = function() {
if (script.readyState == 'loaded' || script.readyState == 'complete') {
script.onreadystatechange = null;
resolve('success: ' + url);
}
};
} else { // Other Browsers
script.onload = function() {
resolve('success: ' + url);
};
}

script.onerror = function() {
reject(Error(url + ' load error!'));
};

script.type = 'text/javascript';
script.id = id;
script.src = `${url}?hash=${id}`;
document.getElementsByTagName('head').item(0).appendChild(script);
});
}

// 加载 JS 后执行 then 的回调函数
loadJs('http://cdn.bootcss.com/jquery/1.9.1/jquery.min.js', 'jq').then(msg => {
console.log(msg);
});

// 加载完所有 JS 后执行 then 的回调函数
const one = 'http://cdn.bootcss.com/jquery/1.9.1/jquery.min.js';
const two = 'https://github.githubassets.com/assets/frameworks-5c304257.js';
Promise.all([loadJs(one, 'jq'), loadJs(two)]).then(results => {
console.log(results);
})
</script>
</body>

</html>

动态加载 CSS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<title>Load CSS</title>
</head>

<body>
<div style="border: 1px solid red">
<div class="post-donate">Dynamic CSS</div>
</div>

<script>
/**
* 异步加载 CSS
*
* @param {String} url CSS 路径
* @param {String} id CSS 的 <link> 的 ID,如果已经存在则不再重复加载,默认为时间戳+随机数
* @return 返回 Promise 对象
*/
function loadCss(url, id = Date.now() + '-' + Math.random()) {
return new Promise(function(resolve, reject) {
// 避免重复加载
if (document.getElementById(id)) {
resolve('success: ' + url);
return;
}

var script = document.createElement('link');

if (script.readyState) { // IE
script.onreadystatechange = function() {
if (script.readyState == 'loaded' || script.readyState == 'complete') {
script.onreadystatechange = null;
resolve('success: ' + url);
}
};
} else { // Other Browsers
script.onload = function() {
resolve('success: ' + url);
};
}

script.onerror = function() {
reject(Error(url + ' load error!'));
};

script.rel = 'stylesheet';
script.id = id;
script.href = `${url}?hash=${id}`;
document.getElementsByTagName('head').item(0).appendChild(script);
});
}

// 加载 CSS 后执行 then 的回调函数
loadCss('http://qtdebug.com/css/style.css').then(msg => {
console.log(msg);
});
</script>
</body>

</html>