如何引用加载当前正在执行的脚本的脚本标记?如何获取当前脚本元素:1. 使用document.currentScript 2. 按 id 选择脚本3. 使用属性选择脚本data-*4. 通过 src 选择脚本5. 遍历所有脚本以找到所需的脚本6. 获取上次执行的脚本

2022-08-29 23:41:43

如何引用加载当前正在运行的 javascript 的脚本元素?

情况是这样的。我有一个“主”脚本在页面中加载到高处,首先在HEAD标签下。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<script type="text/javascript" src="scripts.js"></script>

“scripts.js”中有一个脚本,它需要能够按需加载其他脚本。普通方法对我来说不太有效,因为我需要在不引用HEAD标签的情况下添加新脚本,因为HEAD元素尚未完成渲染:

document.getElementsByTagName('head')[0].appendChild(v);

我想做的是引用加载当前脚本的脚本元素,以便我可以将新的动态加载脚本标记附加到 DOM 之后。

<script type="text/javascript" src="scripts.js"></script>
loaded by scripts.js--><script type="text/javascript" src="new_script1.js"></script>
loaded by scripts.js --><script type="text/javascript" src="new_script2.js"></script>

答案 1

如何获取当前脚本元素:

1. 使用document.currentScript

document.currentScript 将返回其脚本当前正在处理的元素。<script>

<script>
var me = document.currentScript;
</script>

好处

  • 简单明了。可靠。
  • 无需修改脚本标记
  • 使用异步脚本 (defer & async)
  • 使用动态插入的脚本

问题

  • 在较旧的浏览器和 IE 中不起作用。
  • 不适用于模块<script type="module">

2. 按 id 选择脚本

为脚本指定一个 id 属性将允许您使用 document.getElementById() 从内部按 id 轻松选择它。

<script id="myscript">
var me = document.getElementById('myscript');
</script>

好处

  • 简单明了。可靠。
  • 几乎普遍支持
  • 使用异步脚本 (defer & async)
  • 使用动态插入的脚本

问题

  • 需要向脚本标记添加自定义属性
  • id属性可能会导致某些浏览器中的脚本在某些边缘情况下出现奇怪的行为

3. 使用属性选择脚本data-*

为脚本指定一个 data-* 属性将允许您轻松地从内部选择它。

<script data-name="myscript">
var me = document.querySelector('script[data-name="myscript"]');
</script>

与以前的选项相比,这几乎没有什么好处。

好处

  • 简单明了。
  • 使用异步脚本 (defer & async)
  • 使用动态插入的脚本

问题

  • 需要向脚本标记添加自定义属性
  • HTML5,并且不兼容所有浏览器querySelector()
  • 与使用属性相比,支持范围更小id
  • 将绕过边缘情况。<script>id
  • 如果另一个元素在页面上具有相同的数据属性和值,可能会感到困惑。

4. 通过 src 选择脚本

您可以使用选择器按源选择脚本,而不是使用数据属性:

<script src="//example.com/embed.js"></script>

在嵌入中.js:

var me = document.querySelector('script[src="//example.com/embed.js"]');

好处

  • 可靠
  • 使用异步脚本 (defer & async)
  • 使用动态插入的脚本
  • 无需自定义属性或 ID

问题

  • 不适用于本地脚本
  • 会在不同的环境中导致问题,如开发和生产
  • 静态且脆弱。更改脚本文件的位置将需要修改脚本
  • 与使用属性相比,支持范围更小id
  • 如果加载同一脚本两次,将导致问题

5. 遍历所有脚本以找到所需的脚本

我们还可以遍历每个脚本元素,并单独检查每个元素以选择所需的脚本元素:

<script>
var me = null;
var scripts = document.getElementsByTagName("script")
for (var i = 0; i < scripts.length; ++i) {
    if( isMe(scripts[i])){
      me = scripts[i];
    }
}
</script>

这使我们能够在不支持属性的旧浏览器中使用以前的两种技术。例如:querySelector()

function isMe(scriptElem){
    return scriptElem.getAttribute('src') === "//example.com/embed.js";
}

这继承了所采用的任何方法的优点和问题,但不依赖于因此,因此可以在较旧的浏览器中工作。querySelector()

6. 获取上次执行的脚本

由于脚本是按顺序执行的,因此最后一个脚本元素通常是当前正在运行的脚本:

<script>
var scripts = document.getElementsByTagName( 'script' );
var me = scripts[ scripts.length - 1 ];
</script>

好处

  • 简单。
  • 几乎普遍支持
  • 无需自定义属性或 ID

问题

  • 不适用于异步脚本 (defer & async)
  • 不适用于动态插入的脚本

答案 2

由于脚本是按顺序执行的,因此当前执行的脚本标记始终是页面上的最后一个脚本标记,直到那时。因此,要获取脚本标记,您可以执行以下操作:

var scripts = document.getElementsByTagName( 'script' );
var thisScriptTag = scripts[ scripts.length - 1 ];