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 相关文章推荐
基于jquery用于查询操作的实现代码
May 10 Javascript
jQuery对象数据缓存Cache原理及jQuery.data方法区别介绍
Apr 07 Javascript
jquery 自定义容器下雨效果可将下雨图标改为其他
Apr 23 Javascript
JS获取当前日期时间并定时刷新示例
Mar 04 Javascript
javascript实现切换td中的值
Dec 05 Javascript
JS+CSS实现自动改变切换方向图片幻灯切换效果的方法
Mar 02 Javascript
JavaScript类继承及实例化的方法
Jul 25 Javascript
Javascript验证方法大全
Sep 21 Javascript
ASP.NET jquery ajax传递参数的实例
Nov 02 Javascript
详解vue express启动数据服务
Jul 05 Javascript
ES6之Proxy的get方法详解
Oct 11 Javascript
JavaScript实现栈结构Stack过程详解
Mar 07 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
用PHP书写安全的脚本代码
2012/02/05 PHP
详解PHP中cookie和session的区别及cookie和session用法小结
2016/06/12 PHP
Yii安装与使用Excel扩展的方法
2016/07/13 PHP
JavaScript窗口功能指南之在窗口中书写内容
2006/07/21 Javascript
Jquery图形报表插件 jqplot简介及参数详解
2012/10/10 Javascript
Jquery实现视频播放页面的关灯开灯效果
2013/05/27 Javascript
jquery $.each()使用探讨
2013/09/23 Javascript
JavaScript中prototype为对象添加属性的误区介绍
2013/10/15 Javascript
Javascript中浮点数相乘的一个解决方法
2014/06/03 Javascript
nodejs中实现sleep功能实例
2015/03/24 NodeJs
JS实现来回出现文字的状态栏特效代码
2015/10/31 Javascript
win7下安装配置node.js+express开发环境
2015/12/06 Javascript
js实现下拉列表选中某个值的方法(3种方法)
2015/12/17 Javascript
jQuery实现图片局部放大镜效果
2016/03/17 Javascript
基于javascript实现九九乘法表
2016/03/27 Javascript
JavaScript编写一个简易购物车功能
2016/09/17 Javascript
老生常谈angularjs中的$state.go
2017/04/24 Javascript
微信小程序实现滴滴导航tab切换效果
2018/07/24 Javascript
d3绘制基本的柱形图的实现代码
2018/12/12 Javascript
使用nodejs实现JSON文件自动转Excel的工具(推荐)
2020/06/24 NodeJs
vue 获取url参数、get参数返回数组的操作
2020/11/12 Javascript
Python列表list操作符实例分析【标准类型操作符、切片、连接字符、列表解析、重复操作等】
2017/07/24 Python
python+splinter实现12306网站刷票并自动购票流程
2018/09/25 Python
Django中自定义admin Xadmin的实现代码
2019/08/09 Python
Pytorch技巧:DataLoader的collate_fn参数使用详解
2020/01/08 Python
python如何处理程序无法打开
2020/06/16 Python
Python高阶函数与装饰器函数的深入讲解
2020/11/10 Python
Pyside2中嵌入Matplotlib的绘图的实现
2021/02/22 Python
梅西酒窖:Macy’s Wine Cellar
2018/01/07 全球购物
一套PHP的笔试题
2013/05/31 面试题
学生会干部自我鉴定2014
2014/09/18 职场文书
2014年银行个人工作总结
2014/12/05 职场文书
会计专业求职信范文
2015/03/19 职场文书
大学生创业计划书
2019/06/24 职场文书
Node-Red实现MySQL数据库连接的方法
2021/08/07 MySQL
Python字符串格式化方式
2022/04/07 Python