文档加载后获取当前正在运行的JavaScript文件名

4

在文档就绪后,有没有办法获取javascript文件的文件信息(文件名,路径),而不知道加载了多少脚本或它们的加载顺序?

例如:

<html>
  <head>
    <script src="http://www.example.ex/js/js1.js" type="text/javascript">
    <script src="http://www.example.ex/javascript/js2.js" type="text/javascript">
    <script src="http://www.example.ex/scripts/js3.js" type="text/javascript">
    <...>

文件js2.js中有类似以下内容:

$(document).ready(function() {
  // get the filename "js2.js"
}

我可以做到。
var scripts = document.getElementsByTagName("script"),
    scriptLocation = scripts[1].src;

但是索引"[1]"必须是动态的,因为我不知道加载的脚本的顺序。

1
可能是如何获取当前JavaScript文件名的绝对路径的重复问题。正如那里被接受的答案所说:“当然,这只能在初始代码运行时起作用,并且在加载初始脚本后调用的函数中不会有用,因此,如果您需要稍后可用的值,则需要将其保存到变量中。” - Matt Ball
正如那个答案所说,当前运行的脚本始终是 scripts[scripts.length - 1]。你只需要在文档准备好处理程序之前保存名称的引用即可。 - Matt Ball
1
@MattBall 我想你的意思是一个脚本只在加载时执行一次。那么这是我的错误,我应该问:文档完全加载后,当我调用一个函数时,如何知道该函数所在的脚本的索引,而无需事先保存它? 希望你能理解我的意思。 - Miawa
没有保存之前,没有一种100%正确的方法可以做到这一点。你能做的最好的办法是使用堆栈跟踪黑客。没有什么可以证明在任意时间执行的任意JS片段甚至_存在于文件中。我很好奇你为什么要这样做,因为这真的开始像一个XY问题了。 - Matt Ball
5个回答

3
也许提供一个完整的答案比我的评论更有帮助。如果您将此代码放入js2.js中,您将得到想要的结果。关键是在与文件加载同步运行的代码片段中捕获scriptLocation,这意味着不要使用回调函数。
var scripts = document.getElementsByTagName("script"),
    scriptLocation = scripts[scripts.length - 1].src;

$(document).ready(function() {
  // logs the full path corresponding to "js2.js"
  console.log(scriptLocation);
}

没错!这就是我的意思,我已经在使用这个解决方案了。但是我想获得相同的信息,而不需要前两行,或者我需要在每个脚本中编写这些行,并将变量scriptLocation保存为数组。 - Miawa

2
Error.stack 中获取行号和文件名,例如:
console.log((new Error).stack.split("\n"));

请见Error.stack
有关浏览器兼容性,请参见以前的 SO 问题

这是最佳答案,虽然它有点糊弄人而且浏览器的支持不是很完全。 - Campbeln

1

我不是完全确定你想要什么,但如果你想获取DOM中加载的所有脚本的引用,只需执行以下操作:

var scripts = document.getElementsByTagName("script");
for(var i = 0; i < scripts.length; i++){
     var scriptLocation = scripts[i].src;
}

1
这真的没有回答问题。 - Matt Ball
我不能说我完全理解这个问题,但他似乎暗示他需要一个动态索引,我已经提供了。在文档加载后,他现在应该可以访问所有脚本位置。如果 OP 需要其他东西,他可以具体说明。 - Mister Epic

0
var scriptName = [].slice.call(document.getElementsByTagName('script')).pop().getAttribute('src');

document.getElementsByTagName('script') 返回页面脚本的 HTMLCollection。最后一个元素是当前脚本。 HTMLCollection 没有获取最后一个元素的方法,但是通过将集合转换为 Array,我们可以使用 [].slice.call 方法来调用 pop。最后,getAttribute 返回所需的文件名。

相同的代码可以用于向 js 脚本传递参数。

<script src="file.js" args="arg1;arg2">
...
var args = [].slice.call(document.getElementsByTagName('script')).pop().getAttribute('args').split(';');

虽然这段代码片段可能解决了问题,但包括解释真的有助于提高您的帖子质量。请记住,您正在为未来的读者回答问题,而这些人可能不知道您的代码建议原因。请尽量不要在代码中添加过多的解释性注释,因为这会降低代码和解释的可读性! - Blue
:) Add explanation. - Aikon Mogwai

0
var scripts = document.getElementsByTagName("script");
for (var i = 0; i < scripts.length; i++) {
    if (scripts[i].src.match(/<desired filename>/) {
        scriptLocation = scripts[i];
    }
}

如果我正确理解了你的问题,那应该就可以解决了。

是的,但我不知道/<desired filename>/是什么。我只知道它是当前正在执行的文件。 - Miawa
在这种情况下,我不太确定你想要实现什么。 - Vince
我的问题是:有没有办法获取文件信息(文件名,路径)?所以我不知道“期望的文件名”。 - Miawa

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接