2013-01-19 13 views
7

È sicuro assumere che l'ultimo elemento script * nel documento quando lo script è in esecuzione ** è lo script attualmente in esecuzione?È l'ultimo elemento `script` lo script attualmente in esecuzione?

Ad esempio, voglio creare uno script che può essere rilasciato ovunque nel corpo di una pagina e visualizzare un elemento nella stessa posizione. Sto facendo qualcosa del genere:

function getCurrentScriptElement() { 
    var scripts = document.getElementsByTagName('script'); 
    return scripts[scripts.length - 1]; 
} 

var script = getCurrentScriptElement(); 
var view = document.createElement('span'); 

/* Put stuff in our view... */ 

script.parentNode.insertBefore(view, script); 

Supponendo che lo script sia nel corpo del documento, è questo "sicuro?" La funzione getCurrentScriptElement restituirà sempre lo script in esecuzione? In caso contrario, come può essere fatto?

Mi piacerebbe farlo senza legare lo script a uno specifico attributo id o simile, mi piacerebbe che fosse solo posizionale.


ho creato un esempio here che tira in this script. Una risposta suggeriva che altri script potevano creare una condizione in cui un esempio come questo si sarebbe rotto. È possibile aggiungere altri script a questo esempio che lo romperanno?


è stato suggerito che altri script con defer o async attributi potrebbe rompere questo. Qualcuno può dare un esempio di come potrebbe funzionare uno script del genere?

Come ho capito, defer significa caricare prima il DOM, quindi eseguire lo script con il tag defer. In che modo l'attributo defer visualizzato su un altro elemento di script influisce sul comportamento di getCurrentScriptElement?

async, se ho capito bene, significa iniziare il recupero che lo script e mantenere l'analisi del DOM, allo stesso tempo, non aspettare ... ma quando colpisce mia sceneggiatura dovrebbe comunque fermarsi e attendere, giusto?

Non vedo come uno potrebbe influire, qualcuno può fornire un esempio?


* Sono interessato solo a script esterni ai fini di questa domanda.

** Non l'ultimo elemento script nell'intero documento, ma l'ultimo elemento script nel documento al momento dell'esecuzione. Il resto del documento non dovrebbe essere ancora caricato, giusto?

+1

Bene, per cominciare, il tuo esempio non sembra funzionare in IE9. – poke

+0

@poke, non importa;) –

risposta

4

Non è una garanzia assoluta no. Dai un'occhiata a questo JSFiddle: http://jsfiddle.net/jAsek/

<!DOCTYPE html> 
<title>Test case</title> 
<div> 
    <p>At the start</p> 
    <script id="first"> 
     var scr1 = document.createElement("script"); 
     scr1.setAttribute("id", "early"); 
     document.body.appendChild(scr1); 
    </script> 
    <p>After the first script</p> 
    <script id="second"> 
     function getCurrentScriptElement() { 
      var scripts = document.getElementsByTagName('script'); 
      return scripts[scripts.length - 1]; 
     } 

     alert(getCurrentScriptElement().id); 
    </script> 
    <p>At the end</p> 
</div> 

Qui l'avviso riporta l'id dello script iniettato "precoce", non è l'id del attualmente in esecuzione script "secondo".

Non c'è alcuna differenza pratica tra gli script interni ed esterni.

+0

Bello, non ci ho pensato. Mi chiedo se possa essere risolto. Potrebbe sicuramente accadere se qualcos'altro ha fatto scattare una richiesta JSONP. La cosa degli script esterni era una sorta di risposta a un commento su un'altra risposta. –

+0

Interessante. Non è sicuramente così semplice [come pensavo] (http://stackoverflow.com/questions/10762202/alternatives-to-document-write/10810130#comment14920073_10810130). – bfavaretto

+0

Pensare di rendere una regola che lo script non può andare direttamente nel corpo, deve essere annidato in qualcos'altro (ciò si adatta al caso d'uso effettivo che ho in mente). Penso che allora possiamo aggirare questo ... –

1

Non credo che sia un presupposto sicuro, in quanto i browser eseguono codice javascript in modo molto diverso a seconda di un numero di cose (come se si abbiano altri elementi di script in testa, se sono esterni ecc.).

Dovresti semplicemente richiedere alle persone di utilizzare un elemento fittizio con un ID o classe personalizzato. In questo modo potrai anche fare tutto ciò che fai più volte una pagina senza dover eseguire lo script più volte.

Questo è anche ciò che viene fatto quando si utilizzano i widget, ad esempio il pulsante +1 di Google.

Un'alternativa sarebbe utilizzare document.write per scrivere contenuto aggiuntivo mentre lo script viene eseguito. Ciò tuttavia non sostituirà il tag dello script, ma semplicemente aggiungerà qualcosa dopo di esso.

+0

Puoi essere un po 'più chiaro su cosa intendi con il primo paragrafo, o fornire un esempio? Se fornisco un esempio di uno script che funziona, puoi romperlo aggiungendo un altro script? –

+0

Purtroppo, non posso davvero fornirti un esempio o ulteriori dettagli (in realtà volevo scriverlo come commento, ma non a causa della seconda parte della mia risposta). È solo dall'esperienza e dalle discussioni precedenti che il browser si comporta in modo molto diverso su quando e come JS viene caricato ed eseguito. – poke

+0

Non sono interessato alla seconda parte (senza offesa) ... Credo che dovrei aggiungerlo alla domanda. –

Problemi correlati