2010-02-17 18 views
9

Por lo tanto, intento cargar un script dinámicamente y averiguar la ruta de URL en la que se cargó ese script. Entonces, un tipo me dio una solución bastante impresionante a este problema si los scripts están cargados estáticamente (How to get the file-path of the currently executing javascript code). Pero necesito una solución cargada dinámicamente. Por ejemplo:Obtenga la url del archivo js actualmente en ejecución cuando se carga dinámicamente

$(function() 
{ $.getScript("brilliant.js", function(data, textStatus) 
    { // do nothing 
    }); 
}); 

donde "brilliant.js" tiene:

var scripts = document.getElementsByTagName("script"); 
var src = scripts[scripts.length-1].src; 
alert("THIS IS: "+src); 

Lo ideal es que sea imprimir "brilliant.js" o "⟨ nombre de host + basePath ⟩ /brilliant.js"

Actualmente brilliant.js funciona para scripts incluidos estáticamente, pero no para scripts incluidos dinámicamente (como con $ .getScript). ¿Alguien tiene alguna idea? ¿Hay algún lugar en el dom que almacene todos los scripts que se han cargado?

EDITAR: Andras dio una solución bastante buena, aunque probablemente solo funcione para jQuery. Dado que esa es probablemente la biblioteca más popular, y definitivamente lo que voy a usar. Probablemente también se puede extender para otras bibliotecas. Aquí está mi versión simplificada:

var scriptUri; 
curScriptUrl(function(x) 
{ scriptUri = x; 
    alert(scriptUri); 
}); 

function curScriptUrl(callback) 
{ var scripts = document.getElementsByTagName("script"); 
    var scriptURI = scripts[scripts.length-1].src; 

    if(scriptURI != "")   // static include 
    { callback(scriptURI); 
    }else if($ != undefined) // jQuery ajax 
    { $(document).ajaxSuccess(function(e, xhr, s) 
     { callback(s.url); 
     }); 
    } 
} 
+0

Me gusta lo que dijo chamiltongt (abajo), ajax en el código y luego eval() it. Para que sea universalmente accesible, ¿por qué no configurar un micrositio que sirva su código .js? Estaría centralizado y podrá actualizar su código para cada usuario instantáneamente. – logout

Respuesta

8

Cuando su script se carga con jQuery (y supongo que otros marcos también), su script será indistinguible de un script que estaba originalmente en el documento HTML.

jQuery realiza una solicitud para llegar a su script y devuelve la respuesta como el hijo de texto de un <script> nodo. Su navegador no tiene forma de saber de dónde se originó, si fue modificado antes de insertarse, etc. Es solo un nodo de script en lo que a ella respecta.

Sin embargo, puede haber soluciones. En el caso de jQuery, puede conectarse a los eventos de AJAX y explotar el hecho de que se los llama justo después de que se ejecuta el script. Básicamente, esto produciría "brilliant.js" en su ejemplo:

var handler = function (e, xhr, s) { 
    alert(s.url); 
} 

$(document).ajaxSuccess(handler); 

A más elaborado uno:

(function ($, undefined) { 

    /* Let's try to figure out if we are inlined.*/ 
    var scripts = document.getElementsByTagName("script"); 

    if (scripts[scripts.length - 1].src.length === 0) { 
     // Yes, we are inlined. 
     // See if we have jQuery loading us with AJAX here. 
     if ($ !== undefined) { 
      var initialized = false; 
      var ajaxHandler = function (e, xhr, s) { 
       if (!initialized) { 
        initialized = true; 
        alert("Inlined:" + s.url); 
        initmywholejsframework(); 
       } 
      } 

      //If it is, our handler will be called right after this file gets loaded. 
      $(document).ajaxSuccess(ajaxHandler); 

      //Make sure to remove our handler if we ever yield back. 
      window.setTimeout(function() { 
       jQuery(document).unbind("ajaxSuccess", ajaxHandler); 
       if (!initialized) { 
        handleInlinedNonjQuery(); 
       } 
      }, 0); 

     } 
    } else { 
     //We are included. 
     alert("Included:" + scripts[scripts.length - 1].src); 
     initmywholejsframework(); 
    } 

    //Handle other JS frameworks etc. here, if you will. 
    function handleInlinedNonjQuery() { 
     alert("nonJQuery"); 
     initmywholejsframework(); 
    } 

    //Initialize your lib here 
    function initmywholejsframework() { 
     alert("loaded"); 
    } 

})(jQuery); 
+0

Solución fresca. Deseo una forma más universal de resolver esto, pero parece que es lo mejor que hay. Edité mi pregunta anterior para mostrar mi versión de lo que escribiste. –

-1

B T, lo siento si esto no ayuda, pero tengo curiosidad por qué se necesita para hacer esto? La razón por la que estoy preguntando es: ¿no veo por qué no puedes usar las rutas de archivos relativas para cargar estos archivos? Averiguar dónde se encuentra podría hacerse con window.location, pero ¿por qué lo haría? Y en cuanto a cargarlos, ¿no puedes hacer una llamada ajax al archivo y luego evaluarlos?

+0

Además, acabo de recordar una forma más fácil, puede agregar elementos de script dinámicamente a la página. A continuación se muestra un enlace a cómo hacer esto -> http://www.codehouse.com/javascript/articles/external/ – chamiltongt

+0

Estoy creando una biblioteca javascript destinada a ser cargada por dominios externos. Esta no es una pregunta sobre simples archivos javascript. Consulte el siguiente enlace si desea tener más contexto, gracias: http: // stackoverflow.com/questions/2255689/how-to-get-the-file-path-of-the-currenctly-executing-javascript-code. –

+0

+1 para la idea ajax y eval() :) – logout

-1

Esto funciona en todos los navegadores excepto IE y no depende de lo que suponiendo el nombre de un archivo es:

var getErrorLocation = function (error) { 
    var loc, replacer = function (stack, matchedLoc) { 
     loc = matchedLoc; 
    }; 

    if ("fileName" in error) { 
     loc = error.fileName; 
    } else if ("stacktrace" in error) { // Opera 
     error.stacktrace.replace(/Line \d+ of .+ script (.*)/gm, replacer); 
    } else if ("stack" in error) { // WebKit 
     error.stack.replace(/at (.*)/gm, replacer); 
     loc = loc.replace(/:\d+:\d+$/, ""); // remove line number 
    } 
    return loc; 
}; 

try { 
    0(); 
} catch (e) { 
    var scriptURI = getErrorLocation(e); 
} 

alert("THIS IS: " + scriptURI); 
+0

Está cargando el script con $ .getScript() que es equivalente a anexar una etiqueta