动态加载脚本文件

1,148 阅读2分钟

这是我参与11月更文挑战的第20天,活动详情查看:2021最后一次更文挑战

要使用 JavaScript 动态加载脚本文件,基本步骤如下:

  • 创建 script 元素
  • script 元素的 src 属性设置为指向要加载的文件
  • script 元素添加到 DOM
let myScript = document.createElement('script')
myScript.setAttribute('src', './index.js')
document.body.appendChild(myScript)
  • myScript 变量存储对新创建的脚本元素的引用。

  • setAttribute 方法允许我们为要加载的脚本设置 src 值。

  • 最后,我们通过 appendChildscript 元素添加到 body 元素的底部。

下面是一些常见的场景。

先运行动态加载的脚本

body 元素的底部添加 script 元素意味着我们的页面将首先渲染,而不会被 JavaScript 阻止加载和执行。这通常是我们想要的正确行为。现在,在某些情况下,您希望 JavaScript 先于页面可能执行的任何操作运行。为了处理这些情况,我们需要调整代码。

let myScript = document.createElement('script')
myScript.setAttribute('src', './index.js')
myScript.setAttribute('async', 'false')

let head = document.head
head.insertBefore(myScript, head.firstElementChild)

代码中有两个新特性,可以确保在渲染页面上的任何其他内容之前加载并运行外部脚本文件:

  • 我们首先将 script 元素的 async 属性设置为 false。为什么呢?这是因为默认情况下,动态加载的脚本文件是异步加载的。我们想要显式地重写默认行为。

  • 接下来,我们确保在加载页面其余部分之前加载脚本。在 head 元素的顶部添加 script 元素是确保它在页面可能达到的任何其他内容之前运行的最佳位置。

脚本文件加载后运行相关代码

加载一个外部脚本文件,然后立即调用一个函数(或者依赖于加载的脚本中的某些内容)是很常见的。例如:

<scirpt src="./api.js"></scirpt>
<scirpt>
  getArticleDetail({
    id: '1'
  })
</scirpt>

第一个 script 元素加载 api.js 。第二个 script 元素调用依赖于前面的 script 元素加载的 api.js 的内容。所有这些都能正常工作,因为浏览器能很自然地处理了这个场景。

对于动态加载的脚本文件,如果想要类似行为,我们需要额外添加 load 事件来监听我们的 script,一旦监听到,就调用相关的代码:

let myScript = document.createElement('script')
myScript.setAttribute('src', './index.js')
document.body.appendChild(myScript)

myScript.addEventListener('load', scriptLoaded)

function scriptLoaded() {
  console.log('Hi')
}

当加载完 index.js 并执行后,load 事件将被触发,调用 scriptLoaded 事件处理程序。