2010-02-17 3 views
9

Quindi sto provando a caricare uno script in modo dinamico e capire il percorso dell'URL a cui è stato caricato lo script. Quindi un ragazzo mi ha dato una soluzione davvero stupenda a questo problema se gli script sono stati caricati staticamente (How to get the file-path of the currently executing javascript code). Ma ho bisogno di una soluzione caricata dinamicamente. Per esempio:Ottieni l'URL del file js attualmente in esecuzione quando caricato dinamicamente

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

dove "brilliant.js" ha:

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

Idealmente questo dovrebbe neanche stampare "brilliant.js" o "⟨ hostname + BasePath ⟩ /brilliant.js"

Attualmente brilliant.js funziona per gli script inclusi staticamente, ma non per gli script inclusi dinamicamente (come con $ .getScript). Qualcuno ha qualche idea? C'è da qualche parte nella dom che memorizza tutti gli script che sono stati caricati?

EDIT: Andras ha fornito una soluzione piuttosto buona, anche se probabilmente funziona solo per jQuery. Dal momento che è probabilmente la libreria più popolare e sicuramente quello che userò. Probabilmente può essere esteso anche ad altre librerie. Ecco la mia versione semplificata:

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

mi piace quello chamiltongt (sotto) ha detto, ajax nel codice, e quindi eval() esso. Per renderlo universalmente accessibile, perché non impostare un microsito che serve il tuo codice .js. Sarebbe centralizzato e tu sei in grado di aggiornare il tuo codice istantaneamente per ogni utente. – logout

risposta

8

Quando lo script viene caricato con jQuery (e credo che anche altri framework), lo script diventerà indistinguibile da uno script che era originariamente nel documento HTML.

jQuery inoltra una richiesta per lo script e rimette la risposta come testo figlio di uno script < >. Il tuo browser non ha modo di sapere da dove ha avuto origine, se è stato modificato prima dell'inserimento, ecc. È solo un nodo di script per quanto lo riguarda.

Tuttavia, potrebbero esserci soluzioni alternative. Nel caso di jQuery, puoi collegarti agli eventi Ajax e sfruttare il fatto che vengono chiamati subito dopo l'esecuzione dello script. Fondamentalmente, questo produrrebbe "brilliant.js" nel tuo esempio:

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

$(document).ajaxSuccess(handler); 

un più elaborato 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

Soluzione alternativa. Vorrei che esistesse un modo più universale per risolverlo, ma sembra che questo sia il meglio che c'è. Ho modificato la mia domanda sopra per mostrare la mia versione di ciò che hai scritto. –

-1

B T, scusate se questo non aiuta, ma io sono curioso di sapere perchè si avrebbe bisogno di fare questo? Il motivo per cui ti sto chiedendo è che non vedo perché non puoi semplicemente usare i percorsi dei file relativi per caricare questi file? Scoprire dove ti trovi potrebbe essere fatto con window.location, ma perché dovresti? E come per caricarli, non puoi fare una chiamata ajax al file e quindi evalificarli?

+0

Inoltre, ho appena ricordato un modo più semplice, è possibile aggiungere elementi di script alla pagina in modo dinamico. Di seguito è riportato un collegamento a come eseguire questa operazione -> http://www.codehouse.com/javascript/articles/external/ – chamiltongt

+0

Sto creando una libreria javascript che deve essere caricata da domini esterni. Questa non è una domanda su semplici file javascript. Vedere il seguente link se si desidera avere più contesto, grazie: http: // stackoverflow.it/questions/2255689/how-to-get-the-file-path-of-the-currenctly-executing-javascript-code. –

+0

+1 per l'idea di ajax ed eval() :) – logout

-1

Questo funziona in tutti i browser tranne IE e non dipendere da assumere ciò che il nome di un file è:

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

Sta caricando lo script con $ .getScript() che equivale ad aggiungere un tag