代码之家  ›  专栏  ›  技术社区  ›  David Hellsing

获取脚本路径

  •  29
  • David Hellsing  · 技术社区  · 15 年前

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

    如果我把CSS文件放进去 /media/css/mystyles.css 使用类似的东西

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

    浏览器将在 /media/images/myimage.jpg 这是有道理的。

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

    如果我包括 /media/js/myscript.js 把这个代码放进去:

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

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

    13 回复  |  直到 6 年前
        1
  •  39
  •   Community TTT    14 年前

    在DOM中搜索您自己的 <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> )然而,目前很少使用这种方法。

        2
  •  9
  •   Community TTT    7 年前

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

    Can I use 表示撰写本文时70%的Web用户支持。显然,Internet Explorer不支持它,但Edge支持。 MDC 将支持列为chrome 29+、edge、firefox 4.0+、gecko 2.0+、opera 16+和safari 8+。这个 comment by @mjhm 已经指出了这个特性,但在那之前它听起来很实验性。

        3
  •  6
  •   mercator    15 年前

    正如其他海报提到的,您需要首先计算脚本的基本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);
    
        4
  •  6
  •   Timm    12 年前

    受以上Bobine回答的启发,我编写了一个jquery版本。这是一行代码:

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

    编辑:过滤 script 标签由 src 属性,以便我们得到一个要处理的SRC。

        5
  •  2
  •   user1212212    10 年前

    对于异步脚本,脚本标记遍历不起作用。 所以如果: -性能.时间安排 exists (就像在新的非Safari浏览器中一样) &您尚未达到其最大值,或者在加载前已将其最大值推高 &您的脚本是最近加载的内容(amp;Y):

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

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

    performance.webkitSetResourceTimingBufferSize(10000)
    
        6
  •  1
  •   T.J. Crowder    15 年前

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

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

        7
  •  1
  •   QueueHammer    10 年前

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

    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

        8
  •  0
  •   Alsciende    15 年前

    你可以翻过去 <head> 的childnodes,查找 <script> 标记,获取所述脚本的URL,然后计算图像的URL。

        9
  •  0
  •   strager    15 年前

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

    var scriptPath = <?PHP echo json_encode(dirname($_SERVER['SCRIPT_NAME'])); ?>;
    
        10
  •  0
  •   Adam Lear    11 年前

    注意,这个问题上的所有示例都采用最后一次出现的标记,正如所指出的,不支持异步加载。所以,如果您想以完美的方式完成它,您应该另外匹配您的脚本名。事实上,脚本就是这么做的。

    只是突出显示“不完整”代码和类似项目是个问题 http://areaaperta.com/nicescroll/ 使用该版本的代码

        11
  •  0
  •   Chaki_Black    10 年前

    在我的情况下,不是 scripts.length-1 .
    例子:
    在调试模式下JS文件位置: //server/js/app.js
    在生产模式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;
    };
    
        12
  •  0
  •   yorg    10 年前

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

    // 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);
    
        13
  •  0
  •   Krzysztof Przygoda    6 年前

    一行 “探路者” ,当您知道脚本文件名时(此处 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);