Javascript 获取脚本路径

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2161159/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-22 23:01:08  来源:igfitidea点击:

Get script path

javascriptcss

提问by David Hellsing

In CSS, any image path is relative to the CSS file location.

在 CSS 中,任何图像路径都是相对于 CSS 文件位置的。

f.ex if I put the CSS file in /media/css/mystyles.cssand use something like

f.ex 如果我将 CSS 文件放入/media/css/mystyles.css并使用类似的东西

.background:url(../images/myimage.jpg);

The browser will look for the image in /media/images/myimage.jpgwhich makes sense.

浏览器将寻找/media/images/myimage.jpg有意义的图像。

Is it possible to do the same thing in javascript?

是否可以在 javascript 中做同样的事情?

F.ex if I include /media/js/myscript.jsand put this code in there:

F.ex 如果我包含/media/js/myscript.js并将此代码放在那里:

var img = new Image();
img.src = '../images/myimage.jpg';

Th image is not found, since browser is using the HTML file as a starting point, instead of the script location. I would like to be able to use the script location as a starting point, just like CSS does. Is this possible?

找不到图像,因为浏览器使用 HTML 文件作为起点,而不是脚本位置。我希望能够使用脚本位置作为起点,就像 CSS 一样。这可能吗?

回答by bobince

Searching the DOM for your own <script>tag as above is the usual method, yes.

<script>像上面一样在 DOM 中搜索你自己的标签是常用的方法,是的。

However, you usually needn't search too hard: when you're in the body of the script?—?run at include-time?—?you know very well which <script>element you are: the last one. The rest of them can't have been parsed yet.

但是,您通常不需要太用力地搜索:当您在脚本主体中时?—?在包含时运行?—?您很清楚<script>自己是哪个元素:最后一个。其余的还不能被解析。

var scripts= document.getElementsByTagName('script');
var path= scripts[scripts.length-1].src.split('?')[0];      // remove any ?query
var mydir= path.split('/').slice(0, -1).join('/')+'/';  // remove last filename part of path

function doSomething() {
    img.src= mydir+'../images/myimage.jpeg';
}

This doesn't hold true if your script has been linked with <script defer>(or, in HTML5, <script async>). However, this is currently rarely used.

如果您的脚本已与<script defer>(或在 HTML5 中,<script async>)链接,则这不成立。然而,这目前很少使用。

回答by MvG

On more recent browsers, you can use the document.currentScriptproperty to obtain the HTMLScriptelement corresponding to that script, then query its srcproperty.

在较新的浏览器上,您可以使用该document.currentScript属性获取HTMLScript与该脚本对应的元素,然后查询其src属性。

Can I useindicates support by 70% of the web's users, at the time of this writing. Apparently Internet Explorer doesn't support it, but Edge does. MDClists support as Chrome 29+, Edge, Firefox 4.0+, Gecko 2.0+, Opera 16+ and Safari 8+. The comment by @mjhmalready pointed out this feature, but back then it sounded very experimental.

在撰写本文时,Can I use表示 70% 的网络用户支持。显然 Internet Explorer 不支持它,但 Edge 支持。 MDC列出支持 Chrome 29+、Edge、Firefox 4.0+、Gecko 2.0+、Opera 16+ 和 Safari 8+。@mjhm评论已经指出了这个特性,但当时它听起来非常具有实验性。

回答by Thomas - BeeDesk

Inspired by bobince answer above, I wrote a jQuery version. Here is the code in one line:

受上述 bobince 回答的启发,我编写了一个 jQuery 版本。这是一行中的代码:

var scriptpath = $("script[src]").last().attr("src").split('?')[0].split('/').slice(0, -1).join('/')+'/';

Edit: Filter the scripttag by the srcattribute, so that we get a src to work on.

编辑:scriptsrc属性过滤标签,以便我们得到一个 src 来处理。

回答by yannis

As other posters mentioned you need to compute your base url for the script first, you can the script below to find it.

正如其他海报提到的,您需要先计算脚本的基本 url,您可以在下面的脚本中找到它。

// find the base path of a script
var settings = {};
settings.basePath = null;

if (!settings.basePath) {
  (function (name) {
    var scripts = document.getElementsByTagName('script');

    for (var i = scripts.length - 1; i >= 0; --i) {
      var src = scripts[i].src;
      var l = src.length;
      var length = name.length;
      if (src.substr(l - length) == name) {
        // set a global propery here
        settings.basePath = src.substr(0, l - length);

      }
    }
  })('myfile.js');
}

log(settings.basePath);

回答by user1212212

For asynchronous scripts, script tag walking won't do. So if: - performance.timing exists(like in new non-Safari browsers) & You have not reached its max, or have pushed-up its max before loading & Your script was the most recent thing loaded:

对于异步脚本,脚本标记遍历不起作用。因此,如果: - performance.timing存在(例如在新的非 Safari 浏览器中)& 您尚未达到其最大值,或者在加载之前已推高其最大值 & 您的脚本是最新加载的内容:

performance.getEntries().slice(-1)[0].name 

To push-up the max, do something like this:

要提高最大值,请执行以下操作:

performance.webkitSetResourceTimingBufferSize(10000)

回答by QueueHammer

I wrote a class to find get the path of scripts that works with delayed loading and async script tags. It's based on inspecting the stack trace and there are a couple of functions to format the results but it's intended to be basic. If nothing else use it as a reference.

我编写了一个类来查找使用延迟加载和异步脚本标签的脚本的路径。它基于检查堆栈跟踪,并且有几个函数可以格式化结果,但它是基本的。如果没有别的,请将其用作参考。

function ScriptPath() {
  var scriptPath = '';
  try {
    //Throw an error to generate a stack trace
    throw new Error();
  }
  catch(e) {
    //Split the stack trace into each line
    var stackLines = e.stack.split('\n');
    var callerIndex = 0;
    //Now walk though each line until we find a path reference
    for(var i in stackLines){
      if(!stackLines[i].match(/http[s]?:\/\//)) continue;
      //We skipped all the lines with out an http so we now have a script reference
      //This one is the class constructor, the next is the getScriptPath() call
      //The one after that is the user code requesting the path info (so offset by 2)
      callerIndex = Number(i) + 2;
      break;
    }
    //Now parse the string for each section we want to return
    pathParts = stackLines[callerIndex].match(/((http[s]?:\/\/.+\/)([^\/]+\.js)):/);
  }

  this.fullPath = function() {
    return pathParts[1];
  };

  this.path = function() {
    return pathParts[2];
  };

  this.file = function() {
    return pathParts[3];
  };

  this.fileNoExt = function() {
    var parts = this.file().split('.');
    parts.length = parts.length != 1 ? parts.length - 1 : 1;
    return parts.join('.');
  };
}

Full source

完整来源

回答by T.J. Crowder

(If base[Rubens's answer] doesn't work for you. Edit: Apparently he removed it, but I thought it was relevant; see baseon the W3C site.)

(如果base[Rubens's answer] 对您不起作用。编辑:显然他删除了它,但我认为它是相关的;请参阅baseW3C 站点。)

It's possible, but it's a pain. :-) You have to search the DOM for the scripttag that imported your script, and then grab its srcvalue. That's how script.aculo.usdoes its module auto-loading; you can refer to the scriptaculous.jsfile for an example.

这是可能的,但这是一种痛苦。:-) 您必须在 DOM 中搜索script导入脚本的标签,然后获取其src值。这就是script.aculo.us它的模块自动加载的方式;您可以参考scriptaculous.js文件作为示例。

回答by Alsciende

You can flip through <head>'s childNodes, find your <script>tag, get the url of said script, and compute the url of your image.

您可以翻阅<head>的 childNodes,找到您的<script>标签,获取所述脚本的 url,并计算您的图像的 url。

回答by strager

One way is to put the path in the script itself:

一种方法是将路径放在脚本本身中:

var scriptPath = <?PHP echo json_encode(dirname($_SERVER['SCRIPT_NAME'])); ?>;

回答by Chaki_Black

In my case it isn't scripts.length-1.
Example:
In debug mode js file location: //server/js/app.js
In prod mode js file location: //server/js-build/app.js
The file name is known; the single way to find path by it's name:

就我而言,它不是scripts.length-1
示例:
在调试模式下js文件位置://server/js/app.js
在prod模式下js文件位置://server/js-build/app.js
文件名已知;按名称查找路径的单一方法:

getExecutionLocationFolder() {
    var fileName = "app.js";
    var scriptList = $("script[src]");
    var jsFileObject = $.grep(scriptList, function(el) {
        var currentElement = el.src.contains(fileName);
        return currentElement;
    });
    var jsFilePath = jsFileObject[0].src;
    var jsFileDirectory = jsFilePath.substring(0, jsFilePath.lastIndexOf("/") + 1);
    return jsFileDirectory;
};