要使用 JavaScript 动态加载脚本文件,基本步骤如下:
- 创建
script
元素 - 将
script
元素的src
属性设置为指向要加载的文件 - 将
script
元素添加到 DOM
let myScript = document.createElement('script')
myScript.setAttribute('src', '/path/to/js/file.js')
// myScript.src='/path/to/js/file.js'
document.body.appendChild(myScript)
myScript
变量存储对新创建的脚本元素的引用。setAttribute
方法允许我们为要加载的脚本设置src
值。- 最后,我们通过
appendChild
将script
元素添加到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
元素是确保它在页面可能达到的任何其他内容之前运行的最佳位置。
加载一个外部脚本文件,然后立即调用一个函数(或者依赖于加载的脚本中的某些内容)是很常见的。例如:
<script src="./api.js"></script>
<script>
getArticleDetail({ id: '1' })
</script>
第一个 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
事件处理程序。