有的时候需要动态加载javascript文件,并且在加载成功后执行回调函数。要实现这样的功能,可以使用<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); } //调用 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) { //全部加载完成后执行的回调函数 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); } }; //调用 loadScript(['./jquery.min.js','./echarts.min.js','./vue.min.js'],function(){ console.log('onload'); });
上述代码使用了arraySync方案来处理异步,如果条件允许,你也可以使用promise来解决,效果都是一样的。
我的项目中是需要从json文件中读取配置,取到的数据中有需要动态加载的js列表,然后使用上述的批量加载js函数进行处理,下面给出整体代码,有需要的可以搭配使用哦~
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); } };
我自己是一名从事了多年开发的web前端老程序员,目前辞职在做自己的web前端私人定制课程,今年年初我花了一个月整理了一份最适合2019年学习的web前端学习干货,各种框架都有整理,送给每一位前端小伙伴,想要获取的可以关注我的头条号并在后台私信我:前端,即可免费获取。
作者:R狮子歌歌
链接:https://www.jianshu.com/p/997818dbf339
本文暂时没有评论,来添加一个吧(●'◡'●)