获取脚本路径

时间:2010-01-29 10:05:58

标签: javascript css

在CSS中,任何图像路径都与CSS文件位置相关。

f.ex如果我将CSS文件放在/media/css/mystyles.css中并使用类似

的内容
.background:url(../images/myimage.jpg);

浏览器会在/media/images/myimage.jpg中查找有意义的图片。

是否可以在javascript中执行相同的操作?

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

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

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

13 个答案:

答案 0 :(得分:41)

如上所述,在DOM中搜索您自己的<script>标记是常见的方法,是的。

但是,你通常不需要太努力地搜索:当你在脚本体内 - 在包含时运行 - 你很清楚你是哪个<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';
}

如果您的脚本已与<script defer>(或在HTML5中,<script async>)相关联,则不适用。但是,目前很少使用它。

答案 1 :(得分:9)

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

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

答案 2 :(得分:6)

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

// 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);

答案 3 :(得分:6)

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

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

修改:按script属性过滤src标记,以便我们可以使用src。

答案 4 :(得分:2)

对于异步脚本,脚本标记行走不会。 因此,如果: - performance.timing exists(与新的非Safari浏览器一样) &安培;您尚未达到最大值,或在加载前已将其最大值推高 &安培;你的脚本是最新加载的东西:

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

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

performance.webkitSetResourceTimingBufferSize(10000)

答案 5 :(得分:1)

(如果base [鲁本斯的回答]不适合你。编辑:显然他删除了它,但我认为它是相关的;请参阅W3C网站上的base。)

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

答案 6 :(得分:1)

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

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

答案 7 :(得分:0)

您可以浏览<head>的childNodes,找到您的<script>代码,获取所述脚本的网址,然后计算您图片的网址。

答案 8 :(得分:0)

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

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

答案 9 :(得分:0)

请注意,此问题上的所有示例都会出现LAST标记,并且指出不支持异步加载。因此,如果你想以完美的方式做到这一点,你应该与你的脚本名称相匹配。事实上,scriptaculous就是这样做的。

这是一个问题,“不完整”的代码被突出显示,像http://areaaperta.com/nicescroll/这样的项目使用该版本的代码

答案 10 :(得分:0)

就我而言,它不是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;
};

答案 11 :(得分:0)

您可以通过解析文档标记并将其与文档位置进行比较来检索脚本路径。

// get relative document path to script folder
var pathToScript=function(scriptFileName){
    // scan document to get script location
    var sclist = document.getElementsByTagName("script");
    var found = null;
    for(var i=0;i<sclist.length&&!found;i++){
        // check if tag have source (avoid local scripts tags)
        if(typeof(sclist[i].src)=="string"){
            // remove arguments and extract file basename
            var file = sclist[i].src.split("?")[0].split("/").pop();
            // get path if found
            if(file==scriptFileName)found = sclist[i].src.split("?")[0];
        }
    }
    // compare with document location
    if(found){
        var _from = document.location.href.split("/");
        var _to__ = found.split("/");
        // remove files names
        _from.pop();_to__.pop();
        // remove common pathes
        while(_from.length>0&&_to__.length>0&&_from[0]==_to__[0]){
            _from.shift();_to__.shift();
        }
        // add parent dir offset if any
        while(_from.length>0){
            _to__.unshift("..");_from.pop();
        }
        // return relative document path to script folder
        return _to__.length>0?(_to__.join("/")+"/"):"";
    }else{
        throw("\npathToScript Error :\nscript source '"+scriptFileName+"' not found in document.");
    }
};

// use in script file "myscript.js" :
var pathToMe = pathToScript("myscript.js");
console.log("my dir : "+pathToMe);

答案 12 :(得分:0)

一行“Pathfinder”,当您知道脚本文件名(此处为include.js)时:

// Script file name
var file = 'include.js';

// jQuery version
var path = (src = jQuery('script[src$="' + file + '"]').attr('src')).substring(0, src.lastIndexOf("/") + 1);
// jQuery with error handling
var path = (src = jQuery('script[src$="' + file + '"]').attr('src') ? src : 'Path/Not/Found/').substring(0, src.lastIndexOf("/") + 1);

// Plain JS version
var path = (src = document.querySelector('script[src$="' + file + '"]').src).substring(0, src.lastIndexOf("/") + 1);
// Plain JS with error handling
var path = (src = (script = document.querySelector('script[src$="' + file + '"]')) ? script.src : 'Path/Not/Found/').substring(0, src.lastIndexOf("/") + 1);