Irgendeine Idee, warum der folgende Code das Skriptelement nicht zum DOM hinzufügt?
var code = "<script></script>";
$("#someElement").append(code);
Irgendeine Idee, warum der folgende Code das Skriptelement nicht zum DOM hinzufügt?
var code = "<script></script>";
$("#someElement").append(code);
Antworten:
Ich habe Probleme gesehen, bei denen einige Browser einige Änderungen nicht berücksichtigen, wenn Sie sie direkt ausführen (was bedeutet, dass Sie den HTML-Code aus Text erstellen, wie Sie es mit dem Skript-Tag versuchen), aber wenn Sie sie mit integrierten Befehlen ausführen Dinge laufen besser. Versuche dies:
var script = document.createElement( 'script' );
script.type = 'text/javascript';
script.src = url;
$("#someElement").append( script );
Von: JSON für jQuery
$("#someElement")[0].appendChild( script );
Die gute Nachricht ist:
Es funktioniert zu 100%.
Fügen Sie einfach etwas in das Skript-Tag ein, z alert('voila!');
. Die richtige Frage, die Sie vielleicht stellen möchten: "Warum habe ich sie nicht im DOM gesehen?".
Karl Swedberg hat den Kommentar des Besuchers auf der jQuery-API-Site gut erklärt . Ich nicht möchte alle seine Worte wiederholen, können Sie direkt lesen es hier (ich fand es schwer zu navigieren durch die Kommentare dort) .
Alle Einfügemethoden von jQuery verwenden intern eine domManip-Funktion, um Elemente vor und nach dem Einfügen in das DOM zu bereinigen / zu verarbeiten. Die domManip-Funktion zieht unter anderem alle einzufügenden Skriptelemente heraus und führt sie durch eine "evalScript-Routine", anstatt sie mit dem Rest des DOM-Fragments zu injizieren. Es fügt die Skripte separat ein, wertet sie aus und entfernt sie dann aus dem DOM.
Ich glaube, dass einer der Gründe, warum jQuery dies tut, darin besteht, Fehler zu vermeiden, die unter bestimmten Umständen beim Einfügen von Skripten in Internet Explorer auftreten können. Außerdem wird vermieden, dass dasselbe Skript wiederholt eingefügt / ausgewertet wird (was möglicherweise zu Problemen führen kann), wenn es sich in einem enthaltenden Element befindet, das Sie einfügen und dann im DOM verschieben.
Als nächstes fasse ich die schlechten Nachrichten zusammen, indem ich mithilfe der .append()
Funktion ein Skript hinzufüge.
Und die schlechte Nachricht ist ..
Sie können Ihren Code nicht debuggen.
Ich scherze nicht, selbst wenn Sie ein debugger;
Schlüsselwort zwischen der Zeile hinzufügen, die Sie als Haltepunkt festlegen möchten, erhalten Sie am Ende nur den Aufrufstapel des Objekts, ohne den Haltepunkt im Quellcode zu sehen (ganz zu schweigen davon, dass dies der Fall ist Das Schlüsselwort funktioniert nur im Webkit-Browser. Alle anderen gängigen Browser scheinen dieses Schlüsselwort wegzulassen .
Wenn Sie vollständig verstehen, was Ihr Code tut, ist dies ein kleiner Nachteil. Wenn Sie dies nicht tun, werden Sie debugger;
überall ein Schlüsselwort hinzufügen , um herauszufinden, was mit Ihrem (oder meinem) Code nicht stimmt. Wie auch immer, es gibt eine Alternative. Vergessen Sie nicht, dass Javascript HTML-DOM nativ manipulieren kann.
Problemumgehung.
Verwenden Sie Javascript (nicht jQuery), um HTML-DOM zu bearbeiten
Wenn Sie die Debugging-Fähigkeit nicht verlieren möchten, können Sie die native HTML-DOM-Manipulation mit Javascript verwenden. Betrachten Sie dieses Beispiel:
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);
Da ist es, genau wie früher, nicht wahr? Und vergessen Sie nicht, alle Objekte, auf die verwiesen wird und die nicht mehr benötigt werden, um Speicherlecks zu vermeiden, im DOM oder im Speicher zu bereinigen. Sie können diesen Code zum Aufräumen verwenden:
document.body.removechild(document.body.lastChild);
delete UnusedReferencedObjects; // replace UnusedReferencedObject with any object you created in the script you load.
Der Nachteil dieser Problemumgehung besteht darin, dass Sie möglicherweise versehentlich ein doppeltes Skript hinzufügen, und das ist schlecht. Von hier aus können Sie die .append()
Funktion leicht nachahmen , indem Sie vor dem Hinzufügen eine Objektüberprüfung hinzufügen und das Skript direkt nach dem Hinzufügen aus dem DOM entfernen. Betrachten Sie dieses Beispiel:
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;
}
Auf diese Weise können Sie ein Skript mit Debugging-Funktion hinzufügen, ohne sich vor Skriptduplizitäten zu schützen. Dies ist nur ein Prototyp, den Sie für alles erweitern können, was Sie möchten. Ich habe diesen Ansatz verwendet und bin damit sehr zufrieden. Sicher genug, ich werde niemals jQuery verwenden.append()
, um ein Skript hinzuzufügen.
$.getScript
ist in jQuery integriert.
Mit der Funktion jQuery kann eine JavaScript-Datei dynamisch geladen werdengetScript
$ .getScript ('http://www.whatever.com/shareprice/shareprice.js', function () { Display.sharePrice (); });
Jetzt wird das externe Skript aufgerufen, und wenn es nicht geladen werden kann, wird es ordnungsgemäß beeinträchtigt.
eval()
.
Was meinst du mit "nicht arbeiten"?
jQuery erkennt, dass Sie versuchen, ein SCRIPT-Element zu erstellen, und führt den Inhalt des Elements automatisch im globalen Kontext aus. Erzählst du mir, dass das bei dir nicht funktioniert? - -
$('#someElement').append('<script>alert("WORKING");</script>');
Bearbeiten: Wenn Sie das SCRIPT-Element nicht im DOM sehen (z. B. in Firebug), nachdem Sie den Befehl ausgeführt haben, wird jQuery, wie gesagt, den Code ausführen und dann das SCRIPT-Element löschen - ich glaube, dass SCRIPT-Elemente werden immer an den Körper angehängt ... aber trotzdem - die Platzierung hat in dieser Situation absolut keinen Einfluss auf die Codeausführung.
Das funktioniert:
$('body').append($("<script>alert('Hi!');<\/script>")[0]);
Es scheint, als ob jQuery mit Skripten etwas Kluges macht, sodass Sie das HTML-Element anstelle des jQuery-Objekts anhängen müssen.
Versuchen Sie dies kann hilfreich sein:
var fileref=document.createElement('script');
fileref.setAttribute("type","text/javascript");
fileref.setAttribute("src","scriptAnalytics.js");
document.getElementsByTagName("head")[0].appendChild(fileref);
Ich möchte das Gleiche tun, aber ein Skript-Tag in einem anderen Frame anhängen!
var url = 'library.js';
var script = window.parent.frames[1].document.createElement('script' );
script.type = 'text/javascript';
script.src = url;
$('head',window.parent.frames[1].document).append(script);
<script>
...
...jQuery("<script></script>")...
...
</script>
Das </script>
Literal innerhalb des Strings beendet das gesamte Skript, um zu vermeiden, "</scr" + "ipt>"
dass es stattdessen verwendet werden kann.
"\x3cscript\x3e\x3c/script\x3e"
. In XHTML müssen Sie nur einen auskommentierten CDATA-Block einfügen.
</
, was nicht erlaubt ist. Siehe stackoverflow.com/questions/236073/…
Das Hinzufügen der Quell-URL zur Skriptdatei hat geholfen, wie auf dieser Seite erwähnt: https://blog.getfirebug.com/2009/08/11/give-your-eval-a-name-with-sourceurl/
Ihr Skript wird ausgeführt, Sie können es einfach nicht verwenden document.write
. Verwenden Sie eine Warnung, um sie zu testen und die Verwendung zu vermeiden document.write
. Die Anweisungen Ihrer js-Datei mit document.write
werden nicht ausgeführt und der Rest der Funktion wird ausgeführt.
Dies ist meiner Meinung nach die beste Lösung. Google Analytics wird auf diese Weise injiziert.
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); })();
Sie benötigen jQuery nicht, um ein Skript-DOM-Element zu erstellen . Es kann mit Vanilla ES6 wie folgt gemacht werden:
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!'))
Es muss nicht in a eingeschlossen werden Promise
, aber auf diese Weise können Sie das Versprechen beim Laden des Skripts auflösen und so die Race-Bedingungen für Skripte mit langer Laufzeit verhindern.
Skript an body anhängen:
$(document).ready(function() {
$("<script>", { src : "bootstrap.min.js", type : "text/javascript" }).appendTo("body");
});
Eine andere Möglichkeit, dies zu tun, wenn Sie Code anhängen möchten, besteht darin, die document.createElement
Methode zu verwenden, aber dann .innerHTML
anstelle von .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 );
Ich habe versucht , diese ein und funktioniert gut. Ersetzen Sie einfach das <
Symbol damit \x3C
.
// With Variable
var code = "\x3Cscript>SomeCode\x3C/script>";
$("#someElement").append(code);
oder
//Without Variable
$("#someElement").append("\x3Cscript>SomeCode\x3C/script>");
Sie können den Code hier testen .
Kann so versuchen
var code = "<script></" + "script>";
$("#someElement").append(code);
Der einzige Grund, warum Sie dies nicht tun können, "<script></script>"
ist, dass die Zeichenfolge in Javascript nicht zulässig ist, da die DOM-Ebene nicht analysieren kann, was js und was HTML ist.
Ich habe ein npm
Paket geschrieben, mit dem Sie eine HTML-Zeichenfolge, einschließlich Skript-Tags , an einen Container anhängen können die Skripte ausführen
Beispiel:
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)
Finden Sie es hier: https://www.npmjs.com/package/appendhtml
Erstellen Sie einfach ein Element, indem Sie es mit jQuery analysieren.
<div id="someElement"></div>
<script>
var code = "<script>alert(123);<\/script>";
$("#someElement").append($(code));
</script>
Arbeitsbeispiel: https://plnkr.co/edit/V2FE28Q2eBrJoJ6PUEBz