script标签加载问题?

最近发现一个比较奇怪的问题

image.png

如下代码

a.js

console.log('load a');

const script = document.createElement('script');
const src = document.createAttribute('src');
src.value = 'b.js';
script.setAttributeNode(src);
document.head.append(script);

b.js

console.log('load b');

const c = 100;

index.html

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title></title>
        <script src="a.js"></script>
    </head>
    <body>
        <script>
            console.log(c);
        </script>
    </body>
</html>

结果就报错了

image.png

这是怎么回事? 我在index里面引入a, 在a里面引入b, 为什么index里面就不能访问b里面的变量?
推断可能是加载问题, 但是不知道怎么解决
image.png

阅读 3k
6 个回答

动态脚本的加载不会阻塞主页面,他会在加载完成后立即执行

在 JS 中对 HTML 的修改,至少要等到下一帧才可以生效,也就是说修改与渲染并不是同步的。
而如果这个修改还涉及到网络请求,那么就不只是下一帧的问题了,因为网络请求的时间不可忽略。
所以你的代码顺序实际上是这样的:

graph LR
subgraph 第一帧 渲染 HTML 执行 ajs
A1(执行 ajs) -->
A1_1(添加 bjs) -->
A3(执行 HTML 中的代码块)
end
A1_1 -. bjs加载中 .-> B0
A3 -->B0
subgraph 第n帧 执行 bjs
B0(bjs 加载完成) -->
B1(执行 bjs)
end
  • 实线代表时间顺序
  • 虚线表示逻辑顺序

let/const 不会直接修改全局,你用 var 就没问题。

上面大佬已经说了原理,解决的话可以考虑放到 setTimeout 里面延迟执行。

        setTimeout(() => {
            console.log(c);
        }, 1000);

目前找到的解决办法是使用document.write

image.png

image.png

不过这种情况只能让script标签在head里的写法

动态添加script是异步的,里面定义的变量只有执行完毕后才能访问,可以监听 load 事件来判断:

script.onload = function () {
  console.log(xxx);
}
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题