Qualche idea sul perché il pezzo di codice qui sotto non aggiunge l'elemento di script al DOM?
var code = "<script></script>";
$("#someElement").append(code);
Qualche idea sul perché il pezzo di codice qui sotto non aggiunge l'elemento di script al DOM?
var code = "<script></script>";
$("#someElement").append(code);
Risposte:
Ho riscontrato problemi in cui alcuni browser non rispettano alcune modifiche quando le esegui direttamente (per cui intendo creare l'HTML dal testo come se stessi provando con il tag dello script), ma quando le esegui con i comandi integrati le cose vanno meglio. Prova questo:
var script = document.createElement( 'script' );
script.type = 'text/javascript';
script.src = url;
$("#someElement").append( script );
Da: JSON per jQuery
$("#someElement")[0].appendChild( script );
La buona notizia è:
Funziona al 100%.
Basta aggiungere qualcosa all'interno del tag dello script come alert('voila!');
. La domanda giusta che potresti voler porre forse, "Perché non l'ho vista nel DOM?".
Karl Swedberg ha fornito una bella spiegazione al commento del visitatore nel sito dell'API jQuery . Io non voglio ripetere tutte le sue parole, è possibile leggere direttamente lì qui (ho trovato difficile da navigare attraverso i commenti lì) .
Tutti i metodi di inserimento di jQuery utilizzano internamente una funzione domManip per pulire / elaborare gli elementi prima e dopo che sono stati inseriti nel DOM. Una delle cose che fa la funzione domManip è estrarre tutti gli elementi di script che stanno per essere inseriti ed eseguirli attraverso una "routine evalScript" anziché iniettarli con il resto del frammento DOM. Inserisce gli script separatamente, li valuta e quindi li rimuove dal DOM.
Credo che uno dei motivi per cui jQuery faccia questo sia quello di evitare errori "Autorizzazione negata" che possono verificarsi in Internet Explorer quando si inseriscono script in determinate circostanze. Evita inoltre di inserire / valutare ripetutamente lo stesso script (che potrebbe potenzialmente causare problemi) se si trova all'interno di un elemento contenitore che si sta inserendo e quindi spostando nel DOM.
La prossima cosa è che riassumerò quali sono le cattive notizie usando la .append()
funzione per aggiungere uno script.
E le cattive notizie sono ...
Non è possibile eseguire il debug del codice.
Non sto scherzando, anche se aggiungi una debugger;
parola chiave tra la linea che vuoi impostare come punto di interruzione, finirai per ottenere solo lo stack di chiamate dell'oggetto senza vedere il punto di interruzione sul codice sorgente (per non parlare del fatto che questo la parola chiave funziona solo nel browser webkit, tutti gli altri principali browser sembrano omettere questa parola chiave) .
Se capisci perfettamente cosa fa il tuo codice, questo sarà un piccolo inconveniente. Ma se non lo fai, finirai per aggiungere una debugger;
parola chiave in tutto il luogo solo per scoprire cosa c'è che non va nel tuo (o nel mio) codice. Comunque, c'è un'alternativa, non dimenticare che JavaScript può manipolare nativamente il DOM HTML.
Soluzione.
Usa javascript (non jQuery) per manipolare il DOM HTML
Se non vuoi perdere la funzionalità di debug, puoi utilizzare la manipolazione DOM HTML nativa javascript. Considera questo esempio:
var script = document.createElement("script");
script.type = "text/javascript";
script.src = "path/to/your/javascript.js"; // use this for linked script
script.text = "alert('voila!');" // use this for inline script
document.body.appendChild(script);
Eccolo, proprio come ai vecchi tempi non è vero. E non dimenticare di ripulire le cose sia nel DOM che nella memoria per tutti gli oggetti a cui viene fatto riferimento e che non sono più necessari per evitare perdite di memoria. Puoi considerare questo codice per ripulire le cose:
document.body.removechild(document.body.lastChild);
delete UnusedReferencedObjects; // replace UnusedReferencedObject with any object you created in the script you load.
Lo svantaggio di questa soluzione alternativa è che potresti accidentalmente aggiungere uno script duplicato, e questo è male. Da qui puoi simulare leggermente la .append()
funzione aggiungendo una verifica oggetto prima di aggiungere e rimuovendo lo script dal DOM subito dopo che è stato aggiunto. Considera questo esempio:
function AddScript(url, object){
if (object != null){
// add script
var script = document.createElement("script");
script.type = "text/javascript";
script.src = "path/to/your/javascript.js";
document.body.appendChild(script);
// remove from the dom
document.body.removeChild(document.body.lastChild);
return true;
} else {
return false;
};
};
function DeleteObject(UnusedReferencedObjects) {
delete UnusedReferencedObjects;
}
In questo modo, puoi aggiungere script con funzionalità di debug mentre sei al sicuro dalla duplicità degli script. Questo è solo un prototipo, puoi espanderlo per quello che vuoi che sia. Ho usato questo approccio e abbastanza soddisfatto di questo. Abbastanza sicuro non userò mai jQuery .append()
per aggiungere uno script.
$.getScript
è integrato in jQuery.
È possibile caricare dinamicamente un file JavaScript utilizzando la funzione jQuerygetScript
$ .getScript ('http://www.whatever.com/shareprice/shareprice.js', function () { Display.sharePrice (); });
Ora verrà chiamato lo script esterno e, se non può essere caricato, si degraderà con grazia.
eval()
.
Cosa intendi con "non funzionante"?
jQuery rileva che stai tentando di creare un elemento SCRIPT e eseguirà automaticamente il contenuto dell'elemento nel contesto globale. Mi stai dicendo che questo non funziona per te? -
$('#someElement').append('<script>alert("WORKING");</script>');
Modifica: se non vedi l'elemento SCRIPT nel DOM (ad esempio in Firebug) dopo aver eseguito il comando perché jQuery, come ho detto, eseguirà il codice e quindi eliminerà l'elemento SCRIPT - Credo che gli elementi SCRIPT vengono sempre aggiunti al corpo ... ma comunque - il posizionamento non ha assolutamente alcun effetto sull'esecuzione del codice in questa situazione.
Questo funziona:
$('body').append($("<script>alert('Hi!');<\/script>")[0]);
Sembra che jQuery stia facendo qualcosa di intelligente con gli script, quindi è necessario aggiungere l'elemento html anziché l'oggetto jQuery.
Prova questo può essere utile:
var fileref=document.createElement('script');
fileref.setAttribute("type","text/javascript");
fileref.setAttribute("src","scriptAnalytics.js");
document.getElementsByTagName("head")[0].appendChild(fileref);
<script>
...
...jQuery("<script></script>")...
...
</script>
L' </script>
all'interno della stringa termina letterali l'intero script, per evitare che "</scr" + "ipt>"
può essere utilizzato invece.
"\x3cscript\x3e\x3c/script\x3e"
. In XHTML, devi solo inserire un blocco CDATA commentato.
</
ciò che non è permesso. Vedi stackoverflow.com/questions/236073/…
L'aggiunta di sourceURL nel file di script ha aiutato come indicato in questa pagina: https://blog.getfirebug.com/2009/08/11/give-your-eval-a-name-with-sourceurl/
Il tuo script è in esecuzione, non puoi usarlo document.write
. Utilizzare un avviso per testarlo ed evitare di utilizzarlo document.write
. Le istruzioni del tuo file js con document.write
non verranno eseguite e il resto della funzione verrà eseguito.
Questa è quella che penso sia la soluzione migliore. Google Analytics viene iniettato in questo modo.
var (function(){
var p="https:" == document.location.protocol ? "https://" : "http://";
d=document,
g=d.createElement('script'),
s=d.getElementsByTagName('script')[0];
g.type='text/javascript';
g.src=p+'url-to-your-script.js';
s.parentNode.insertBefore(g,s); })();
Non è necessario jQuery per creare un elemento DOM di script . Può essere fatto con vaniglia ES6 in questo modo:
const script = "console.log('Did it work?')"
new Promise((resolve, reject) => {
(function(i,s,o,g,r,a,m){
a=s.createElement(o),m=s.getElementsByTagName(o)[0];
a.innerText=g;
a.onload=r;m.parentNode.insertBefore(a,m)}
)(window,document,'script',script, resolve())
}).then(() => console.log('Sure did!'))
Non è necessario racchiuderlo in a Promise
, ma ciò consente di risolvere la promessa quando lo script viene caricato, contribuendo a prevenire le condizioni di competizione per gli script di lunga durata.
Aggiungi script al corpo:
$(document).ready(function() {
$("<script>", { src : "bootstrap.min.js", type : "text/javascript" }).appendTo("body");
});
Un altro modo per farlo se si desidera aggiungere il codice è utilizzare il document.createElement
metodo ma quindi utilizzare .innerHTML
invece di .src
.
var script = document.createElement( 'script' );
script.type = 'text/javascript';
script.innerHTML = 'alert("Hey there... you just appended this script to the body");';
$("body").append( script );
Puoi provare così
var code = "<script></" + "script>";
$("#someElement").append(code);
L'unico motivo per cui non puoi farlo "<script></script>"
è perché la stringa non è consentita all'interno di JavaScript perché il livello DOM non può analizzare ciò che è js e ciò che è HTML.
Ho scritto un npm
pacchetto che ti consente di prendere una stringa HTML, inclusi tag script e aggiungerla a un contenitore mentre esecuzione degli script
Esempio:
import appendHtml from 'appendhtml';
const html = '<p>Hello</p><script src="some_js_file.js"></script>';
const container = document.getElementById('some-div');
await appendHtml(html, container);
// appendHtml returns a Promise, some_js_file.js is now loaded and executed (note the await)
Lo trovi qui: https://www.npmjs.com/package/appendhtml
Basta creare un elemento analizzandolo con jQuery.
<div id="someElement"></div>
<script>
var code = "<script>alert(123);<\/script>";
$("#someElement").append($(code));
</script>
Esempio di lavoro: https://plnkr.co/edit/V2FE28Q2eBrJoJ6PUEBz