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 获取span标签中的值的代码 支持ie与firefox
Aug 24 Javascript
javascript 实现键盘上下左右功能的小例子
Sep 15 Javascript
Javascript动态引用CSS文件的2种方法介绍
Jun 06 Javascript
zepto中使用swipe.js制作轮播图附swipeUp,swipeDown不起效果问题
Aug 27 Javascript
基于JS实现PHP的sprintf函数实例
Nov 14 Javascript
JS动态改变浏览器标题的方法
Apr 06 Javascript
BootStrap的table表头固定tbody滚动的实例代码
Aug 24 Javascript
微信小程序 页面跳转传参详解
Oct 28 Javascript
Node.js之网络通讯模块实现浅析
Apr 01 Javascript
JS 中document.write()的用法和清空的原因浅析
Dec 04 Javascript
微信小程序new Date()方法失效问题解决方法
Jul 29 Javascript
Vue提供的三种调试方式你知道吗
Jan 18 Vue.js
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
PHP+MYSQL开发工具及资源收藏
2007/01/02 PHP
php 判断数组是几维数组
2013/03/20 PHP
PHP中批量生成静态html(命令行下运行PHP)
2014/04/19 PHP
php简单统计在线人数的方法
2016/05/10 PHP
js 获取浏览器高度和宽度值(多浏览器)
2009/09/02 Javascript
基于javascript的JSON格式页面展示美化方法
2014/07/02 Javascript
深入理解Angular2 模板语法
2016/08/07 Javascript
jquery实现图片切换代码
2016/10/13 Javascript
详解Vue.js组件可复用性的混合(mixin)方式和自定义指令
2017/09/06 Javascript
微信小程序实现手势图案锁屏功能
2018/01/30 Javascript
浅谈JavaScript面向对象--继承
2019/03/20 Javascript
Express结合Webpack的全栈自动刷新
2019/05/23 Javascript
nuxt配置通过指定IP和端口访问的实现
2020/01/08 Javascript
jQuery实现简易聊天框
2020/02/08 jQuery
在vscode 中设置 vue模板内容的方法
2020/09/02 Javascript
记一次vue跨域的解决
2020/10/21 Javascript
Python时间戳与时间字符串互相转换实例代码
2013/11/28 Python
python杀死一个线程的方法
2015/09/06 Python
Python创建对称矩阵的方法示例【基于numpy模块】
2017/10/12 Python
Python三种遍历文件目录的方法实例代码
2018/01/19 Python
python 的 scapy库,实现网卡收发包的例子
2019/07/23 Python
5行Python代码实现图像分割的步骤详解
2020/05/25 Python
Python web如何在IIS发布应用过程解析
2020/05/27 Python
Pyinstaller加密打包应用的示例代码
2020/06/11 Python
python excel和yaml文件的读取封装
2021/01/12 Python
澳大利亚当地社区首选的光学商店:1001 Optical
2019/08/24 全球购物
什么是.net的Remoting技术
2016/07/08 面试题
建筑工程实习自我鉴定
2013/09/19 职场文书
保安的辞职报告怎么写
2014/01/20 职场文书
八一建军节演讲稿
2014/09/10 职场文书
工作犯错保证书
2015/05/11 职场文书
毕业论文指导老师意见
2015/06/04 职场文书
病房管理制度范本
2015/08/06 职场文书
2019脱贫攻坚工作总结报告范本!
2019/08/06 职场文书
Python的这些库,你知道多少?
2021/06/09 Python
MySQL 原理优化之Group By的优化技巧
2022/08/14 MySQL