JS脚本加载后执行相应回调函数的操作方法


Posted in Javascript onFebruary 28, 2018

项目中经常会遇到这样的问题:当某个 js 脚本加载完成后再执行相应任务,但很多朋友可能并不知道怎么判断我们要加载的 js 文件是否加载完成,如果没有加载完成我们就调用 js 文件里面的函数是不会成功的。本文主要讲解怎么在成功加载 js 文件后再执行相应回调任务。

基本思路

我们可以动态的创建 <script> 元素,然后通过更改它的 src 属性来加载脚本,但是怎么知道这个脚本文件加载完成了呢?因为有些函数需要在脚本加载完成才能调用。IE 浏览器中可以使用 <script> 元素的 onreadystatechange 来监控加载状态的改变,并通过判断它的 readyState 是 loaded 或 complete 来判断脚本是否加载完成。而非 IE 浏览器可以使用 onload 来直接判断脚本是否加载完成。

动态脚本简单示例

一个 简单 的实现过程如下:

// IE下:
var HEAD = document.getElementsByTagName('head')[0] || document.documentElement
var src = 'http://xxxxxx.com'
var script = document.createElement('script')
script.setAttribute('type','text/javascript')
script.onreadystatechange = function() {
 if(this.readyState === 'loaded' || this.readyState === 'complete') {
  console.log('加载成功!')
 }
}
script.setAttribute('src', src)
HEAD.appendChild(script)
// Chrome等现代浏览器:
var HEAD = document.getElementsByTagName('head')[0] || document.documentElement;
var src = 'http://xxxxxx.com'
var script = document.createElement('script')
script.setAttribute('type','text/javascript')
script.onload = function() {
 console.log('加载成功!')
}
script.setAttribute('src', src)
HEAD.appendChild(script)

原理很简单,根据这两个简单的原理,我们进行一些修改,我把改成了两个函数,分别是 串行加载 和 并行加载 。

串行和并行动态脚本

当传一个包含多个JS文件路径的数组时,串行加载函数从第一个脚本文件加载开始,每加载成功一个便开始加载下一个脚本文件,全部加载完成后执行回调函数。而并行加载是一开始便加载全部的脚本文件,也就是他们从同一点开始加载,当全部加载完成后,执行回调函数。

/** 
 * 串行加载指定的脚本
 * 串行加载[异步]逐个加载,每个加载完成后加载下一个
 * 全部加载完成后执行回调
 * @param {Array|String} scripts 指定要加载的脚本
 * @param {Function} callback 成功后回调的函数
 * @return {Array} 所有生成的脚本元素对象数组
 */
function seriesLoadScripts(scripts, callback) {
 if(typeof(scripts) !== 'object') {
  var scripts = [scripts];
 }
 var HEAD = document.getElementsByTagName('head')[0] || document.documentElement;
 var s = [];
 var last = scripts.length - 1;
 //递归
 var recursiveLoad = function(i) {
  s[i] = document.createElement('script');
  s[i].setAttribute('type','text/javascript');
  // Attach handlers for all browsers
  // 异步
  s[i].onload = s[i].onreadystatechange = function() {
   if(!/*@cc_on!@*/0 || this.readyState === 'loaded' || this.readyState === 'complete') {
    this.onload = this.onreadystatechange = null; 
    this.parentNode.removeChild(this);
    if(i !== last) {
     recursiveLoad(i + 1);
    } else if (typeof(callback) === 'function') {
     callback()
    };
   }
  }
  // 同步
  s[i].setAttribute('src', scripts[i]);
  HEAD.appendChild(s[i]);
 };
 recursiveLoad(0);
}
/**
 * 并行加载指定的脚本
 * 并行加载[同步]同时加载,不管上个是否加载完成,直接加载全部
 * 全部加载完成后执行回调
 * @param {Array|String} scripts 指定要加载的脚本
 * @param {Function} callback 成功后回调的函数
 * @return {Array} 所有生成的脚本元素对象数组
 */ 
function parallelLoadScripts(scripts, callback) {
 if(typeof(scripts) !== 'object') {
  var scripts = [scripts];
 }
 var HEAD = document.getElementsByTagName('head')[0] || document.documentElement;
 var s = [];
 var loaded = 0;
 for(var i = 0; i < scripts.length; i++) {
  s[i] = document.createElement('script');
  s[i].setAttribute('type','text/javascript');
  // Attach handlers for all browsers
  // 异步
  s[i].onload = s[i].onreadystatechange = function() {
   if(!/*@cc_on!@*/0 || this.readyState === 'loaded' || this.readyState === 'complete') {
    loaded++;
    this.onload = this.onreadystatechange = null;
    this.parentNode.removeChild(this);
    if(loaded === scripts.length && typeof(callback) === 'function') callback();
   }
  };
  // 同步
  s[i].setAttribute('src',scripts[i]);
  HEAD.appendChild(s[i]);
 }
}

在这里是把 <script> 标签动态的插入到页面中的 <head> 标签内部,并且加载完成后标签元素会被自动移除。

使用方法

这里声明了一个数组变量,里面包含了两个远程的JS文件地址(当然 <script> 标签调用脚本是支持跨域的):

var scripts = [ 
 "http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js",
 "http://wellstyled.com/files/jquery.debug/jquery.debug.js"
];
// 这两个文件分别是 jQuery 1.4.的库文件和 jQuery Debug 插件
// 然后你可以使用下面的方法调用并在成功后执行回调了。
parallelLoadScripts(scripts, function() { 
 /*
 debug = new $.debug({ 
  posTo : { x:'right', y:'bottom' },
  width: '480px',
  height: '50%',
  itemDivider : '<hr>',
  listDOM : 'all'
 });
 */
 console.log('脚本加载完成啦');
});

总结

以上所述是小编给大家介绍的JS脚本加载后执行相应回调函数操作方法,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
js 图片随机不定向浮动的实现代码
Jul 02 Javascript
JQuery对class属性的操作实现按钮开关效果
Oct 11 Javascript
javascript中为某个元素指定事件的三种方式
Aug 07 Javascript
js实现圆盘记速表
Aug 03 Javascript
跟我学习javascript的this关键字
May 28 Javascript
AngularJS入门教程之AngularJS表达式
Apr 18 Javascript
jsp 自动编译机制详细介绍
Dec 01 Javascript
利用JS做网页特效_大图轮播(实例讲解)
Aug 09 Javascript
js中bool值的转换及“&amp;&amp;”、“||”、 “!!”详解
Dec 21 Javascript
详解Angular6.0使用路由步骤(共7步)
Jun 29 Javascript
优化Vue项目编译文件大小的方法步骤
May 27 Javascript
JavaScript实现省市区三级联动
Feb 13 Javascript
vue+webpack 打包文件 404 页面空白的解决方法
Feb 28 #Javascript
webpack项目调试以及独立打包配置文件的方法
Feb 28 #Javascript
vue-cli+webpack项目 修改项目名称的方法
Feb 28 #Javascript
vue 组件 全局注册和局部注册的实现
Feb 28 #Javascript
vue 自定义全局方法,在组件里面的使用介绍
Feb 28 #Javascript
Vue2.0子同级组件之间数据交互方法
Feb 28 #Javascript
bootstrap table支持高度百分比的实例代码
Feb 28 #Javascript
You might like
推荐文章系统(一)
2006/10/09 PHP
我的论坛源代码(八)
2006/10/09 PHP
php park、unpark、ord 函数使用方法(二进制流接口应用实例)
2010/10/19 PHP
PHP代码审核的详细介绍
2013/06/13 PHP
用javascript做拖动布局的思路
2008/05/31 Javascript
jquery+json实现的搜索加分页效果
2010/03/31 Javascript
js操作时间(年-月-日 时-分-秒 星期几)
2010/06/20 Javascript
js中判断数字\字母\中文的正则表达式 (实例)
2012/06/29 Javascript
javascript图像处理—仿射变换深度理解
2013/01/16 Javascript
关于jquery中全局函数each使用介绍
2013/12/10 Javascript
JavaScript中的setUTCDate()方法使用详解
2015/06/11 Javascript
jQuery手动点击实现图片轮播特效
2020/04/20 Javascript
基于javascript实现彩票随机数生成(升级版)
2020/04/17 Javascript
对angularjs框架下controller间的传值方法详解
2018/10/08 Javascript
小程序数据通信方法大全(推荐)
2019/04/15 Javascript
axios封装,使用拦截器统一处理接口,超详细的教程(推荐)
2019/05/02 Javascript
微信小程序Page中data数据操作和函数调用方法
2019/05/08 Javascript
基于vue手写tree插件的那点事儿
2019/08/20 Javascript
[02:04]2020年夜魇暗潮预告片
2020/10/30 DOTA
下载给定网页上图片的方法
2014/02/18 Python
Python程序设计入门(5)类的使用简介
2014/06/16 Python
仅用50行Python代码实现一个简单的代理服务器
2015/04/08 Python
Python实现的RSS阅读器实例
2015/07/25 Python
深入学习python的yield和generator
2016/03/10 Python
Python中的延迟绑定原理详解
2019/10/11 Python
PYTHON发送邮件YAGMAIL的简单实现解析
2019/10/28 Python
Python接口测试环境搭建过程详解
2020/06/29 Python
详解Anaconda安装tensorflow报错问题解决方法
2020/11/01 Python
python中绕过反爬虫的方法总结
2020/11/25 Python
纯CSS3实现漂亮的input输入框动画样式库(Text input love)
2018/12/29 HTML / CSS
Europcar英国:英国汽车和货车租赁
2017/01/21 全球购物
法律工作求职自荐信
2013/10/31 职场文书
专题民主生活会对照检查材料思想汇报
2014/09/29 职场文书
党员干部对十八届四中全会的期盼
2014/10/17 职场文书
基层党员学习党的群众路线教育实践活动心得体会
2014/11/04 职场文书
win11无法登录onedrive错误代码0x8004def7怎么办 ?
2022/04/05 数码科技