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
Get script path
提问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.
编辑:script按src属性过滤标签,以便我们得到一个 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('.');
};
}
回答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;
};

