有的時候需要動態(tài)加載javascript文件,并且在加載成功后執(zhí)行回調(diào)函數(shù)舞蔽。要實現(xiàn)這樣的功能,可以使用
<script>
元素的load
事件(IE9+申屹、chrome焙贷、FireFox等)和onreadystatechange
事件(IE8以下)
當你只需要加載一個js文件時拍皮,可以使用這段代碼:
function loadScript(src, callback) {
var script = document.createElement('script'),
head = document.getElementsByTagName('head')[0];
script.type = 'text/javascript';
script.charset = 'UTF-8';
script.src = src;
if (script.addEventListener) {
script.addEventListener('load', function () {
callback();
}, false);
} else if (script.attachEvent) {
script.attachEvent('onreadystatechange', function () {
var target = window.event.srcElement;
if (target.readyState == 'loaded') {
callback();
}
});
}
head.appendChild(script);
}
//調(diào)用
loadScript('http://cdn.staticfile.org/jquery/1.6.2/jquery.min.js',function(){
console.log('onload');
});
當你需要加載多個js文件時:
function loadScript(src, callback) {
arraySync(function (one, i, c) {
var cur_script = document.createElement("script");
cur_script.type = 'text/javascript';
cur_script.charset = 'UTF-8';
cur_script.src = one;
cur_script.addEventListener('load', function () {
c(0, {
i: i,
v: {}
});
}, false);
document.head.appendChild(cur_script)
}, src, function (err, r) {
//全部加載完成后執(zhí)行的回調(diào)函數(shù)
if (err) {
dhtmlxAlert(err.message);
} else {
callback()
}
});
}
//處理異步歹叮,不用promise的方案
function arraySync(bsFunc, ar) {
var callback = arguments[arguments.length - 1];
if (ar.length == 0) {
callback(0, []);
return;
}
var sendErr = false;
var finishNum = ar.length;
var result = [];
var args = [0, 0];
for (var index = 2; index < arguments.length - 1; ++index) {
args.push(arguments[index]);
}
args.push(function (err, r) {
if (err) {
if (!sendErr) {
sendErr = true;
callback(err);
}
return;
}
--finishNum;
result[r.i] = r.v;
if (finishNum == 0) {
callback(0, result);
}
});
for (var i = 0; i < ar.length; ++i) {
args[0] = ar[i];
args[1] = i;
bsFunc.apply(null, args);
}
};
//調(diào)用
loadScript(['./jquery.min.js','./echarts.min.js','./vue.min.js'],function(){
console.log('onload');
});
上述代碼使用了arraySync
方案來處理異步,如果條件允許铆帽,你也可以使用promise
來解決咆耿,效果都是一樣的。
我的項目中是需要從json文件中讀取配置爹橱,取到的數(shù)據(jù)中有需要動態(tài)加載的js列表萨螺,然后使用上述的批量加載js函數(shù)進行處理,下面給出整體代碼愧驱,有需要的可以搭配使用哦~
var loadScript = function (callback) {
//讀取json
var request = new XMLHttpRequest();
request.open("get", "package.json");
request.send(null);
request.onload = function () {
if (request.status == 200) {
var package = JSON.parse(request.responseText);
//合并dependencies和plugins對象
Object.assign(package.dependencies, package.plugins);
var scriptUrls = [];
for (var i in package.dependencies) {
scriptUrls.push(package.dependencies[i])
}
//異步載入script
arraySync(function (one, i, c) {
var cur_script = document.createElement("script");
cur_script.type = 'text/javascript';
cur_script.charset = 'UTF-8';
cur_script.src = one;
cur_script.addEventListener('load', function () {
c(0, {
i: i,
v: {}
});
}, false);
document.head.appendChild(cur_script)
}, scriptUrls, function (err, r) {
if (err) {
dhtmlxAlert(err.message);
} else {
callback()
}
});
}
}
}
//處理異步慰技,不用promise的方案
function arraySync(bsFunc, ar) {
var callback = arguments[arguments.length - 1];
if (ar.length == 0) {
callback(0, []);
return;
}
var sendErr = false;
var finishNum = ar.length;
var result = [];
var args = [0, 0];
for (var index = 2; index < arguments.length - 1; ++index) {
args.push(arguments[index]);
}
args.push(function (err, r) {
if (err) {
if (!sendErr) {
sendErr = true;
callback(err);
}
return;
}
--finishNum;
result[r.i] = r.v;
if (finishNum == 0) {
callback(0, result);
}
});
for (var i = 0; i < ar.length; ++i) {
args[0] = ar[i];
args[1] = i;
bsFunc.apply(null, args);
}
};