javascript - how - Obtener ruta de script
javascript get filename from url (13)
En CSS, cualquier ruta de imagen es relativa a la ubicación del archivo CSS.
f.ex si pongo el archivo CSS en /media/css/mystyles.css
y uso algo como
.background:url(../images/myimage.jpg);
El navegador buscará la imagen en /media/images/myimage.jpg
que tiene sentido.
¿Es posible hacer lo mismo en javascript?
F.ex. Si incluyo /media/js/myscript.js
y pongo este código allí:
var img = new Image();
img.src = ''../images/myimage.jpg'';
La imagen no se encuentra, ya que el navegador utiliza el archivo HTML como punto de partida, en lugar de la ubicación del script. Me gustaría poder usar la ubicación del script como punto de partida, al igual que lo hace CSS. es posible?
Buscar el DOM para su propia etiqueta <script>
como se muestra arriba es el método usual, sí.
Sin embargo, normalmente no necesita buscar demasiado: cuando se encuentra en el cuerpo de la secuencia de comandos, ejecútelo en tiempo de inclusión, sabe muy bien qué elemento <script>
es: el último. El resto de ellos no pueden haber sido analizados todavía.
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'';
}
Esto no es cierto si su script se ha vinculado con <script defer>
(o, en HTML5, <script async>
). Sin embargo, esto se usa raramente actualmente.
Como mencionaron otros carteles, primero debe calcular su URL base para el script, puede encontrar el script a continuación para encontrarlo.
// 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);
En los navegadores más recientes, puede usar la propiedad document.currentScript
para obtener el elemento HTMLScript
correspondiente a ese script y luego consultar su propiedad src
.
¿Puedo usar? Indica el soporte por el 70% de los usuarios de la web, en el momento de este escrito. Aparentemente, Internet Explorer no lo admite, pero Edge sí. MDC listas de MDC compatibles con Chrome 29+, Edge, Firefox 4.0+, Gecko 2.0+, Opera 16+ y Safari 8+. El comentario de @mjhm ya señalaba esta característica, pero en aquel entonces sonaba muy experimental.
En mi caso no es scripts.length-1
.
Ejemplo:
En la ubicación del archivo js en modo depuración: //server/js/app.js
En la ubicación del archivo prod de modo js: //server/js-build/app.js
El nombre del archivo es conocido; La única forma de encontrar la ruta por su nombre:
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;
};
Escribí una clase para encontrar la ruta de los scripts que funcionan con etiquetas de script de carga retrasada y asíncronas. Se basa en la inspección del seguimiento de la pila y hay un par de funciones para formatear los resultados, pero su intención es ser básica. Si nada más lo usas como referencia.
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(''.'');
};
}
Inspirado por la respuesta de Bobince anterior, escribí una versión de jQuery. Aquí está el código en una línea:
var scriptpath = $("script[src]").last().attr("src").split(''?'')[0].split(''/'').slice(0, -1).join(''/'')+''/'';
Editar: filtre la etiqueta de script
por el atributo src
, para que podamos obtener un src para trabajar.
Para los scripts asíncronos, el desplazamiento de etiquetas de script no es suficiente. Por lo tanto, si: - exists performance.timing (como en los nuevos navegadores que no son Safari) y no ha alcanzado su máximo, o ha aumentado su capacidad máxima antes de cargar & Su script fue lo más reciente que se cargó:
performance.getEntries().slice(-1)[0].name
Para presionar al máximo, haz algo como esto:
performance.webkitSetResourceTimingBufferSize(10000)
Puede hojear los nodos secundarios de <head>
, encontrar su etiqueta <script>
, obtener la url de dicho script y calcular la url de su imagen.
TENGA EN CUENTA que todas las muestras de esta pregunta toman la ÚLTIMA aparición de etiquetas, y como se señaló, no admiten la carga asíncrona. por lo tanto, si desea hacerlo de manera perfecta, debe coincidir con SU nombre de script ADICIONALMENTE. de hecho, scriptaculous hace eso.
solo es un problema que el código "incompleto" esté resaltado y los proyectos como http://areaaperta.com/nicescroll/ utilicen esa versión del código
Una forma es poner la ruta en el script mismo:
var scriptPath = <?PHP echo json_encode(dirname($_SERVER[''SCRIPT_NAME''])); ?>;
Una línea "Pathfinder" , cuando conoce el nombre del archivo de script (aquí 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);
puede recuperar la ruta del script analizando las etiquetas del documento y comparándola con la ubicación del documento.
// 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);
(Si la base
[la respuesta de Rubens] no funciona para usted. Edit: Aparentemente, él lo eliminó, pero pensé que era relevante; consulte la base
en el sitio de W3C).
Es posible, pero es un dolor. :-) Debe buscar en el DOM la etiqueta de script
que importó su secuencia de comandos y luego tomar su valor src
. Así es como script.aculo.us
realiza la carga automática de su módulo; puede scriptaculous.js archivo scriptaculous.js para ver un ejemplo.