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

情况是这样的。我有一个“主”脚本被加载在页面的高,第一件事下的头标签。

<!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>

当前回答

遵循以下简单步骤获取当前正在执行的脚本块的引用:

在脚本块中放入一些随机的唯一字符串(在每个脚本块中必须是唯一的/不同的) document.getElementsByTagName('script')的迭代结果,从每个内容中查找唯一的字符串(从innerText/textContent属性获得)。

示例(ABCDE345678是唯一的ID):

<script type="text/javascript">
var A=document.getElementsByTagName('script'),i=count(A),thi$;
for(;i;thi$=A[--i])
  if((thi$.innerText||thi$.textContent).indexOf('ABCDE345678'))break;
// Now thi$ is refer to current script block
</script>

顺便说一句,对于你的情况,你可以简单地使用老式的document.write()方法来包含另一个脚本。 正如你提到的DOM还没有被呈现,你可以利用浏览器总是以线性顺序执行脚本的事实(除了延迟的脚本将在以后呈现),所以你的文档的其余部分仍然是“不存在”的。 通过document.write()编写的任何内容都将放在调用者脚本之后。

原始HTML页面示例:

<!doctype html>
<html><head>
<script src="script.js"></script>
<script src="otherscript.js"></script>
<body>anything</body></html>

script.js的内容:

document.write('<script src="inserted.js"></script>');

渲染后,DOM结构将变成:

HEAD
  SCRIPT script.js
  SCRIPT inserted.js
  SCRIPT otherscript.js
BODY

其他回答

获取脚本,即当前加载的脚本可以使用

var thisScript = document.currentScript;

您需要在脚本的开头保留一个引用,以便稍后调用

var url = thisScript.src

遵循以下简单步骤获取当前正在执行的脚本块的引用:

在脚本块中放入一些随机的唯一字符串(在每个脚本块中必须是唯一的/不同的) document.getElementsByTagName('script')的迭代结果,从每个内容中查找唯一的字符串(从innerText/textContent属性获得)。

示例(ABCDE345678是唯一的ID):

<script type="text/javascript">
var A=document.getElementsByTagName('script'),i=count(A),thi$;
for(;i;thi$=A[--i])
  if((thi$.innerText||thi$.textContent).indexOf('ABCDE345678'))break;
// Now thi$ is refer to current script block
</script>

顺便说一句,对于你的情况,你可以简单地使用老式的document.write()方法来包含另一个脚本。 正如你提到的DOM还没有被呈现,你可以利用浏览器总是以线性顺序执行脚本的事实(除了延迟的脚本将在以后呈现),所以你的文档的其余部分仍然是“不存在”的。 通过document.write()编写的任何内容都将放在调用者脚本之后。

原始HTML页面示例:

<!doctype html>
<html><head>
<script src="script.js"></script>
<script src="otherscript.js"></script>
<body>anything</body></html>

script.js的内容:

document.write('<script src="inserted.js"></script>');

渲染后,DOM结构将变成:

HEAD
  SCRIPT script.js
  SCRIPT inserted.js
  SCRIPT otherscript.js
BODY

由于脚本是按顺序执行的,因此当前执行的脚本标记始终是页面上的最后一个脚本标记。所以,要获得脚本标签,你可以这样做:

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

这是一个利用文档的填充程序。如果存在CurrentScript,则返回到按ID查找脚本。

<script id="uniqueScriptId">
    (function () {
        var thisScript = document.CurrentScript || document.getElementByID('uniqueScriptId');

        // your code referencing thisScript here
    ());
</script>

如果您在每个脚本标记的顶部包含这个,我相信您将能够始终如一地知道哪个脚本标记正在被触发,并且您还能够在异步回调的上下文中引用脚本标记。

未经测试,所以如果你尝试了,给别人留下反馈。

处理异步和延迟脚本的一种方法是利用onload处理程序——为所有脚本标记设置一个onload处理程序,第一个执行的处理程序应该是你的。

function getCurrentScript(callback) {
  if (document.currentScript) {
    callback(document.currentScript);
    return;
  }
  var scripts = document.scripts;
  function onLoad() {
    for (var i = 0; i < scripts.length; ++i) {
      scripts[i].removeEventListener('load', onLoad, false);
    }
    callback(event.target);
  }
  for (var i = 0; i < scripts.length; ++i) {
    scripts[i].addEventListener('load', onLoad, false);
  }
}

getCurrentScript(function(currentScript) {
  window.console.log(currentScript.src);
});