动态加载js文件以及判断js加载完成
[ 2017/12/01, JavaScript , 5829阅, 0评 ]

常用的动态加载js文件有以下几种方式:

1.直接document.write

document.write("<script src='test.js'><\/script>");

2.动态创建script元素

function loadJS(jsUrl) {
  var _doc = document.getElementsByTagName('head').item(0),
    script = document.createElement('script');
  script.setAttribute('type', 'text/javascript');
  script.setAttribute('src', jsUrl);
  _doc.appendChild(script);
}

loadJS('https://cdn.bootcss.com/angular.js/1.6.6/angular.js')

3.预留一个script标签,然后动态改变src

这几种方法都是异步执行的,也就是说,在加载这些脚本的同时,主页面的脚本继续运行,如果用以上的方法,那下面的代码将得不到预期的效果。

比如现在需要动态加载a.js,并拿到其中的str的值,a.js如下:

var str = "我是str的值";
console.log("我是a.js中的:"+str)

主页面js:

//loadJS()略
loadJS("a.js");
console.log( "主页面动态加载a.js并取其中的变量:" + str );

上述代码执行后a.js中的console执行并输出正确内容,但是主页面的console产生了错误,原因是str is not defined,为什么呢?因为主页面在取str的时候a.js并没有完全加载成功。在有些情况下就需要等待a.js加载完成后才能进一步的操作,所以可以使用下面的方法来解决:

/**
 * 加载远程js文件
 * @param {string} jsUrl 远程js文件地址
 * @param {function} callback 加载完成的回调
 */
export function loadJS(jsUrl, callback) {
  const head = document.getElementsByTagName('head')[0]
  const script = document.createElement('script')
  script.type = 'text/javascript'
  script.src = jsUrl
  // 借鉴了jQuery的script跨域方法
  script.onload = script.onreadystatechange = function() {
    if (
      !this.readyState ||
      this.readyState === 'loaded' ||
      this.readyState === 'complete'
    ) {
      callback && callback()
      // Handle memory leak in IE
      script.onload = script.onreadystatechange = null
      if (head && script.parentNode) {
        head.removeChild(script)
      }
    }
  }
  // Use insertBefore instead of appendChild  to circumvent an IE6 bug.
  head.insertBefore(script, head.firstChild)
}

柿一柿:

loadJS('a.js', function() {
  console.log('加载完成啦!!!' + str)
})

最后,附一个动态加载百度地图资源的栗子:

/**
 * 加载百度地图资源
 * @returns
 */
export function loadBMapJS() {
  const bdAK = '你的AK'
  const BMap_URL = `https://api.map.baidu.com/api?type=webgl&v=3.0&ak=${bdAK}&s=1&callback=onBMapCallback`
  return new Promise((resolve, reject) => {
    if (typeof window.BMapGL !== 'undefined') {
      resolve(window.BMapGL)
      return true
    }
    console.log('初始化百度地图脚本...')
    window.onBMapCallback = function() {
      console.log('百度地图脚本初始化成功...')
      resolve(window.BMapGL)
    }
    const scriptNode = document.createElement('script')
    scriptNode.setAttribute('type', 'text/javascript')
    scriptNode.setAttribute('src', BMap_URL)
    document.body.appendChild(scriptNode)
  })
}

有朋自远方来...评论一下呗O(∩_∩)O