如何创建外联<script>并执行?

最近在做QQ地图的功能。
因为不是所有页面都使用了地图,所以我就想在使用到地图的页面再加载js。
在index.html里面,这样是可以的。

clipboard.png

但是,如果是下面这样:

<script type="text/javascript" id="qqMap"></script>

clipboard.png

clipboard.png

就会报错,“qq is not defined”。

我感觉是顺序的问题,所以就问了,这种追加上去的js方法真的没法用吗?
有没有更好的解决办法呢?

阅读 4.2k
2 个回答

大致可以这样写

<html>

<head>
    <title></title>
    <script id="mAxios"></script>
</head>

<body>
    <script>
        (() => {
            var s = document.getElementById("mAxios");
            console.log(s);
            s.setAttribute("src", "https://cdn.bootcss.com/axios/0.19.0/axios.min.js");
        })();

        window.onload = function () {
            console.log(axios);
        }
    </script>
</body>

</html>

有一点需要注意,这一点可能是引起你的异常的原因:动态加载 script 的 js 代码,一定要写在 <script type="text/javascript" id="qqMap"></script> 的后面。

这是我这边的效果:

clipboard.png

这种按需加载方案是可行的,也是常用做法,你的问题是得确保代码是在script成功加载之后执行,参考下我简化后的按需加载模块

map.js

const KEY = '你的地图密钥';

const onLoad = [];

let TMapInit = false;

let TMapLoad = false;

function init(libraries) {
  if (!TMapInit) {
    const script = document.createElement('script');
    libraries = libraries || 'drawing,geometry,convertor';
    script.src = `//map.qq.com/api/js?v=2.exp&key=${KEY}&libraries=${libraries}&callback=onTMapLoad`;
    document.body.appendChild(script);
    TMapInit = true;
  }
}

/**
 * 接受地图异步回调的函数
 */
window.onTMapLoad = () => {
  TMapLoad = true;
  onLoad.forEach(callback => {
    callback && callback(window.qq.maps);
  });
};

export default {
  onReady(callback, libraries) {
    if (!TMapLoad) {
      if (!TMapInit) init(libraries);
      onLoad.push(callback);
    } else {
      callback && callback(window.qq.maps);
    }
  },
}

使用

import Map from '../map.js'

Map.onReady(maps => {
 //...your code
}, 'lite');
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题