Können Skripten eingefügt werden, die mit innerHTML?
Ich habe versucht, laden einige Skripts in eine Seite mit innerHTML
auf eine <div>
. Es scheint, dass das Skript lädt in den DOM, aber es wird nie ausgeführt (zumindest in Firefox und Chrome). Gibt es eine Möglichkeit, um Skripte ausführen, wenn Sie Sie mit innerHTML
?
Beispielcode:
HTML:
<!DOCTYPE html>
<html>
<body onload="document.getElementById('loader').innerHTML = '<script>alert(\'hi\')<\/script>'">
Shouldn't an alert saying 'hi' appear?
<div id="loader"></div>
</body>
</html>
Du musst angemeldet sein, um einen Kommentar abzugeben.
Verwenden Sie eval() ausführen beliebigen script-code, den Sie eingefügt haben als DOM-text.
MooTools wird dies automatisch für Sie tun, und ich bin mir sicher, dass jQuery würde, sowie (je nach version. jQuery in der version 1.6+ verwendet
eval
). Das spart eine Menge ärger mit der Analyse aus<script>
tags und Flucht Ihre Inhalte, sowie ein paar andere "Fallstricke".In der Regel, wenn Sie gehen, um
eval()
Sie sich, Sie wollen zu erstellen/senden der Skript-code ohne HTML-markup wie<script>
an, diese werden nichteval()
richtig.<script>
tag mitinnerHTML
könnte kurz sein, aber es funktioniert nicht. Es ist alles nur text, bis es ausgeführt wird durcheval()
. Und leidereval()
nicht Parsen von HTML-tags, so dass Sie am Ende mit einer Kette von Problemen.Hier ist eine sehr interessante Lösung für Ihr problem:
http://24ways.org/2005/have-your-dom-and-script-it-too
So verwenden Sie diese anstelle von script-tags:
<img src="empty.gif" onload="alert('test');this.parentNode.removeChild(this);" />
onload
Attribut. Auch dies erfordert eine zusätzliche Datei zu existieren und geladen werden. momo die Lösung ist weniger ein Kompromiss.<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7">
(dies nicht tun, ein Netzwerk Anfrage) Tatsächlich... Sie brauchen NICHT ein Bild, verweisen auf eine nicht vorhandene Bild und stattonload
verwendenonerror
(aber das wird eine Netzwerk Anfrage)Hier ist eine Methode, die rekursiv ersetzt alle Skripte ausführbar sind:
Beispiel nennen:
Können Sie ein Skript erstellen und dann injizieren Sie den Inhalt.
Dies funktioniert in allen Browsern 🙂
document.documentElement
statt.<script>
var g = document.createElement('script');
var s = document.getElementsByTagName('script')[0]; //reference this script
g.text = "alert(\"hi\");"
s.parentNode.insertBefore(g, s);
</script>
<script>
Elemente. E. g.<img onerror="..." src="#">
und<body onload="...">
. Wenn Sie möchten, um technische, das funktioniert nicht in nicht-HTML/SVG-Dokumente, die entweder aufgrund der unbestimmt Verwendung von Namensräumen.Ich habe diesen code, es ist in Ordnung, die
Für jemand, der noch versucht, dies zu tun, Nein, Sie können nicht Spritzen, ein Skript mit
innerHTML
, aber es ist möglich, laden Sie eine Zeichenfolge in einen script-tag mit einemBlob
undURL.createObjectURL
.Habe ich ein Beispiel erstellt, die Sie können, führen Sie einen string als ein Drehbuch und bekommen die 'exports' des Skripts zurückgegeben durch ein Versprechen:
Habe ich diese vereinfacht von meinem eigentlichen Umsetzung, so dass kein Versprechen, dass es keine Fehler in ihm. Aber das Prinzip funktioniert.
Wenn Sie kümmern sich nicht darum, irgendeinen Wert zurück, nachdem das Skript ausgeführt wird, ist es noch leichter; lassen Sie einfach die
Promise
undonload
bits. Sie nicht sogar brauchen, wickeln Sie das Skript oder erstellen Sie die globalenwindow.__load_script_exports_
Eigenschaft.Hier ist eine rekursive Funktion zum festlegen der innerHTML eines Elements, die ich verwenden in unserer ad-server:
Sehen Sie die demo hier.
Krasimir Tsonev hat eine tolle Lösung, die überwindung aller Probleme.
Seine Methode muss nicht mit eval, also keine Leistung noch security Probleme vorhanden.
Es erlaubt das setzen von innerHTML-string enthält html mit js und übersetzen Sie es sofort auf ein DOM-element, während auch führt die js Teile vorhanden sind, die entlang den code. kurz ,einfach und funktioniert genau so, wie Sie wollen.
Genießen seine Lösung:
http://krasimirtsonev.com/blog/article/Convert-HTML-string-to-DOM-element
Wichtige Hinweise:
Verwenden
$(parent).html(code)
stattparent.innerHTML = code
.Den folgenden behebt auch Schriften, die
document.write
und Skripte geladen übersrc
Attribut. Leider auch das funktioniert nicht mit Google-AdSense-scripts.Quelle
Ja, Sie können, aber Sie haben, es zu tun außerhalb des DOM und den Auftrag hat, im Recht zu sein.
...Alarm 'foo'. Das wird nicht funktionieren:
- Und auch dies wird nicht funktionieren, da der Knoten wird zuerst eingefügt:
Versuchen, mit Vorlage und Dokument.importNode. Hier ist ein Beispiel:
HTML:
Könnte man es so machen:
Hier eine Lösung, die nicht
eval
, und arbeitet mit Skripte, verlinkten Skripte , sowie mit Module.Die Funktion erwartet 3 Parameter :
eval('console.log(this)')
und Sie werden sehen, die meisten offensichtlicheeval('let b=100')
.. und dann versuchen, Zugriff aufb
von außerhalb der eval .... viel Glück damit, du wirst es brauchenGabriel Garcia erwähnen, der MutationObservers ist auf dem richtigen Weg, aber nicht ganz für mich arbeiten. Ich bin nicht sicher, ob das war, weil der eine browser Eigenart oder durch einen Fehler auf mein Ende, aber die version, endete für mich zu arbeiten, war die folgende:
Sollte man natürlich ersetzen
element_to_watch
mit dem Namen des Elements, das geändert wird.node.parentElement.added
dient zum speichern der script-tags, die Hinzugefügt werden, umdocument.head
. In der Funktion zum laden der externen Seite, können Sie etwas wie das folgende zu entfernen, die nicht mehr entsprechenden script-tags:Und ein Beispiel für den Anfang einer laden-Funktion:
MutationObserver
jedes mal, wenn ein element an das Dokument angefügt, richtig? Btw, ich Frage mich, warum tun Sie sagen, mein code ist nicht funktionsfähig.Meine Lösung für dieses problem ist es, eine Mutation Observer zu erkennen
<script></script>
Knoten und ersetzen Sie es mit einem neuen<script></script>
Knoten mit der gleichen src. Zum Beispiel:Execute (Java-Script) - tag von innerHTML
Ersetzen Sie Ihre script-element mit div mit einer class-Attribut class="javascript", und schließen Sie es mit
</div>
Nicht ändern Sie den Inhalt, den Sie ausführen wollen (vorher war es im script-tag und nun ist es in den div-tag)
Hinzufügen Stil in Ihre Seite ein...
<style type="text/css"> .javascript { display: none; } </style>
Nun eval ausführen mit jquery(Jquery js sollte bereits im Lieferumfang enthalten)
Erkunden Sie mehr hier, auf meinem blog.