Получить путь к скрипту - PullRequest
30 голосов
/ 29 января 2010

В 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 ]

41 голосов
/ 29 января 2010

Поиск 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>). Однако в настоящее время это редко используется.

9 голосов
/ 04 ноября 2015

В более новых браузерах можно использовать свойство document.currentScript, чтобы получить элемент HTMLScript, соответствующий этому сценарию, а затем запросить его свойство src.

Могу ли я использовать указывает на поддержку 70% пользователей сети, на момент написания этой статьи. По-видимому, Internet Explorer не поддерживает его, но Edge поддерживает. MDC включает поддержку Chrome 29+, Edge, Firefox 4.0+, Gecko 2.0+, Opera 16+ и Safari 8+. Комментарий @ mjhm уже указывал на эту особенность, но тогда это звучало очень экспериментально.

6 голосов
/ 23 ноября 2011

Вдохновленный ответом bobince выше, я написал версию jQuery. Вот код в одной строке:

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

Edit: отфильтруйте тег script по атрибуту src, чтобы мы получили src для работы.

6 голосов
/ 29 января 2010

Как уже упоминалось другими авторами, вам сначала нужно вычислить базовый 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);
2 голосов
/ 03 февраля 2015

Для асинхронных сценариев обход тега сценария не подходит. Так что если: - performance.timing существует (как в новых браузерах без Safari) & Вы не достигли своего максимума или подняли его до загрузки & Ваш скрипт был загружен самым последним:

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

Чтобы увеличить максимум, сделайте что-то вроде этого:

performance.webkitSetResourceTimingBufferSize(10000)
1 голос
/ 04 марта 2014

Я написал класс для поиска пути к скриптам, который работает с отложенной загрузкой и тегами асинхронных скриптов. Он основан на проверке трассировки стека, и есть несколько функций для форматирования результатов, но он должен быть базовым. Если ничто иное не использует его в качестве ссылки.

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('.');
  };
}

Полный источник

1 голос
/ 29 января 2010

(Если base [ответ Рубенса] не работает для вас. Редактировать: Очевидно, он удалил его, но я подумал, что это уместно; см. base на сайте W3C .)

Это возможно, но это боль. :-) Вам нужно найти в DOM тег script, который импортировал ваш скрипт, а затем получить его значение src. Вот как script.aculo.us выполняет автоматическую загрузку модуля; Вы можете обратиться к файлу scriptaculous.js для примера.

0 голосов
/ 28 марта 2018

Одна строка "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);
0 голосов
/ 30 декабря 2014

вы можете получить путь к скрипту, проанализировав теги документа и сравнив его с местоположением документа.

// 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);
0 голосов
/ 18 ноября 2014

В моем случае это не 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;
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...