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 相关文章推荐
javascript中的float运算精度实例分析
Aug 21 Javascript
jquery中获取select选中值的代码
Jun 27 Javascript
Prototype源码浅析 Enumerable部分(二)
Jan 18 Javascript
关于火狐(firefox)及ie下event获取的两种方法
Dec 27 Javascript
jquery设置text的值示例(设置文本框 DIV 表单值)
Jan 06 Javascript
director.js实现前端路由使用实例
Feb 03 Javascript
Js获取当前日期时间及格式化代码
Sep 17 Javascript
Javascript获取图片原始宽度和高度的方法详解
Sep 20 Javascript
Jquery UI实现一次拖拽多个选中的元素操作
Dec 01 Javascript
JavaScript 数据类型详解
Mar 13 Javascript
webpack使用 babel-loader 转换 ES6代码示例
Aug 21 Javascript
最简单的JS实现json转csv的方法
Jan 10 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
smarty的保留变量问题
2008/10/23 PHP
zen cart新进商品的随机排序修改方法
2010/09/10 PHP
浅谈PHP调用Webservice思路及源码分享
2014/06/04 PHP
php中动态修改ini配置
2014/10/14 PHP
调整小数的格式保留小数点后两位
2014/05/14 Javascript
Window.Open如何在同一个标签页打开
2014/06/20 Javascript
jQuery插件jcrop+Fileapi完美实现图片上传+裁剪+预览的代码分享
2015/04/22 Javascript
js兼容pc端浏览器并有多种弹出小提示的手机端浮层控件实例
2015/04/29 Javascript
javascript性能优化之事件委托实例详解
2015/12/12 Javascript
Flow之一个新的Javascript静态类型检查器
2015/12/21 Javascript
JS正则获取HTML元素的方法
2017/03/31 Javascript
五步轻松实现JavaScript HTML时钟效果
2020/03/25 Javascript
js 判断当前时间是否处于某个一个时间段内
2019/09/19 Javascript
JavaScript进阶(三)闭包原理与用法详解
2020/05/09 Javascript
解决ant Design中this.props.form.validateFields未执行的问题
2020/10/27 Javascript
python3使用tkinter实现ui界面简单实例
2014/01/10 Python
python完成FizzBuzzWhizz问题(拉勾网面试题)示例
2014/05/05 Python
编程语言Python的发展史
2014/09/26 Python
Python多线程经典问题之乘客做公交车算法实例
2017/03/22 Python
详解Python下ftp上传文件linux服务器
2018/06/21 Python
完美解决python中ndarray 默认用科学计数法显示的问题
2018/07/14 Python
78行Python代码实现现微信撤回消息功能
2018/07/26 Python
浅谈Python 列表字典赋值的陷阱
2019/01/20 Python
python钉钉机器人运维脚本监控实例
2019/02/20 Python
Python求两点之间的直线距离(2种实现方法)
2019/07/07 Python
python之生产者消费者模型实现详解
2019/07/27 Python
python 定义类时,实现内部方法的互相调用
2019/12/25 Python
Python运行异常管理解决方案
2020/03/09 Python
Python Selenium模块安装使用教程详解
2020/07/09 Python
python空元组在all中返回结果详解
2020/12/15 Python
Python实现简单猜数字游戏
2021/02/03 Python
TensorFlow2.0使用keras训练模型的实现
2021/02/20 Python
和平主题的演讲稿
2014/01/12 职场文书
在HTML5 localStorage中存储对象的示例代码
2021/04/21 Javascript
详细聊聊MySQL中慢SQL优化的方向
2021/08/30 MySQL
Win10 最新稳定版本 21H2开始推送
2022/04/19 数码科技