项目需求:客户端有重复的脚本引入,不想在服务端渲染,备注:此需求常见于小公司比较懒的做法。
关键代码
html 部分
<head>
<meta charset="UTF-8">
<script id="scriptLoader1" src="/js/scriptLoader.js"></script>
<script id="scriptLoader2">
scriptLoader.init(["./your-script.js"]);
</script>
</head>
脚本scriptLoader.js部分:
// 公用script加载器,避免页面引用代码的冗余
(function(window) {
// 构造函数
var ScriptLoader = function() {};
var head = document.getElementsByTagName('head')[0]; // 获取head对象
// 原型对象
ScriptLoader.prototype = {
init: function(scriptArr) {
// scriptArr 是自定义的数组
// commonScriptArr 是通用script数组 重复引用的脚本
var commonScriptArr = [
"/lib/your-script-1.min.js",
"/lib/your-script-2.min.js",
"/lib/your-script-2.min.js",
"/lib/your-script-4.min.js",
"/lib/your-script-6.min.js"
];
// 传参处理:如果存在并且类型不是数组,那么提示程序员参数传递错误
if (!(scriptArr && typeof scriptArr === 'object' && Array == scriptArr.constructor)) {
return alert("请传递数组类型");
}
// 参数存在且是数组 或者 参数不存在的脚本列表处理
var arr = scriptArr ? commonScriptArr.concat(scriptArr) : commonScriptArr; // 加入自定义脚本
this.loadScript(arr); // 异步按序添加head中的脚本
this.removeSelf(); // 移除自身
},
// 异步顺序加载
loadScript: function(urlArr) {
if (!urlArr.length) {
return;
}
var that = this;
var script = document.createElement("script"); // 加载 script
script.type = "text/javascript";
if (script.readyState) {
//IE
script.onreadystatechange = function() {
if (script.readyState == "loaded" || script.readyState == "complete") {
script.onreadystatechange = null;
that.loadScript(urlArr);
}
};
} else {
//Others: Firefox, Safari, Chrome, and Opera
script.onload = function() {
that.loadScript(urlArr);
};
}
var url = urlArr.splice(0, 1)[0]; // 使用第一个,并且对原数组进行减1操作
script.src = url;
head.appendChild(script);
},
// 移除自身脚本
removeSelf: function() {
var scriptLoader1 = document.getElementById("scriptLoader1");
var scriptLoader2 = document.getElementById("scriptLoader2");
scriptLoader1 && head.removeChild(scriptLoader1);
scriptLoader2 && head.removeChild(scriptLoader2);
}
}
window.scriptLoader = new ScriptLoader(); // 暴露给全局对象
})(window);
scriptLoader.init传入的脚本: your-script.js部分
console.log("test);
然后可以测试加载顺序了,不过这种做法,实际上对大型项目是很不友好的,最好是服务端来做。根据项目需求来定,另外,css脚本也同样可以适用此方法,如果存在很多共同的css引用,参考此script的做法。