In Tutorials habe ich gelernt, zu verwenden document.write
. Jetzt verstehe ich, dass dies von vielen verpönt wird. Ich habe es versucht print()
, aber dann wird es buchstäblich an den Drucker gesendet.
Welche Alternativen sollte ich verwenden und warum sollte ich sie nicht verwenden document.write
? Sowohl w3schools als auch MDN verwenden document.write
.
javascript
document.write
DarkLightA
quelle
quelle
print()
beschließt zuwindow.print()
.print()
ist nicht dasselbe wie PHPprint()
. JS sendet die Seite buchstäblich an den Drucker und PHP gibt einfach Code aus.Antworten:
Als empfohlene Alternative können
document.write
Sie die DOM-Manipulation verwenden , um Knotenelemente direkt abzufragen und dem DOM hinzuzufügen.quelle
Der Grund, warum Ihr HTML ersetzt wird, liegt an einer bösen JavaScript-Funktion :
document.write()
.Es ist definitiv "schlechte Form". Es funktioniert nur mit Webseiten, wenn Sie es beim Laden der Seite verwenden. Wenn Sie es zur Laufzeit verwenden, wird Ihr gesamtes Dokument durch die Eingabe ersetzt. Und wenn Sie es als strenge XHTML-Struktur anwenden, ist es nicht einmal gültiger Code.
das Problem:
- Zitat aus dem MDN
document.write()
hat zwei Handlangerdocument.open()
, unddocument.close()
. Wenn das HTML-Dokument geladen wird, ist das Dokument "geöffnet". Wenn das Dokument vollständig geladen wurde, wurde das Dokument "geschlossen". Wenn Siedocument.write()
an dieser Stelle verwenden, wird Ihr gesamtes (geschlossenes) HTML-Dokument gelöscht und durch ein neues (offenes) Dokument ersetzt. Dies bedeutet, dass Ihre Webseite sich selbst gelöscht und eine neue Seite geschrieben hat - von Grund auf neu.Ich glaube,
document.write()
dass der Browser ebenfalls eine Leistungsminderung aufweist (korrigieren Sie mich, wenn ich falsch liege).ein Beispiel:
Dieses Beispiel schreibt Ausgabe an das HTML - Dokument , nachdem die Seite geladen wird.
document.write()
Die bösen Mächte von Watch löschen das gesamte Dokument, wenn Sie auf die Schaltfläche "Ausrotten" klicken:I am an ordinary HTML page. I am innocent, and purely for informational purposes. Please do not <input type="button" onclick="document.write('This HTML page has been succesfully exterminated.')" value="exterminate"/> me!
die Alternativen:
.innerHTML
Dies ist eine wunderbare Alternative, aber dieses Attribut muss an das Element angehängt werden, in das Sie den Text einfügen möchten.Beispiel:
document.getElementById('output1').innerHTML = 'Some text!';
.createTextNode()
ist die vom W3C empfohlene Alternative .Beispiel:
var para = document.createElement('p'); para.appendChild(document.createTextNode('Hello, '));
HINWEIS: Es ist bekannt, dass dies zu Leistungseinbußen führt (langsamer als
.innerHTML
). Ich empfehle.innerHTML
stattdessen zu verwenden.das Beispiel mit der
.innerHTML
Alternative:I am an ordinary HTML page. I am innocent, and purely for informational purposes. Please do not <input type="button" onclick="document.getElementById('output1').innerHTML = 'There was an error exterminating this page. Please replace <code>.innerHTML</code> with <code>document.write()</code> to complete extermination.';" value="exterminate"/> me! <p id="output1"></p>
quelle
document.write()
kann während des Ladens der Seite aufgerufen werden, während der Browser die Seite analysiert. Sobald die Seite analysiert / geladen wurde, wird beim Aufrufen dieser Funktion auch aufgerufendocument.open()
, wodurch die Seite gelöscht und von vorne begonnen wird. Ich kann mir keinen Grund vorstellen, die Funktion während des Ladens der Seite nicht zu verwenden, außer aus Gründen der Konsistenz mit der Art und Weise, wie Sie einer Seite zu einem anderen Zeitpunkt Inhalt hinzufügen. Das Dokument wird geschlossen, sobald der Browser das Parsen des Dokuments abgeschlossen hat.document.write()
scheint immer noch die beste Lösung für den lokalen Fallback von CDN zu sein . Ich habe getElementById / innerHTML noch nicht ausprobiert, aber eine createElement / insertBefore-Lösung stellt sich als nicht synchron heraus .document.write()
nachdem die Seiten geladen wurden, da das Dokument gelöscht und bei jedem Aufruf der Funktion erneut geöffnet werden muss..innerHTML
macht nichts davon, also bin ich mir ziemlich sicher, dass ich gelesen habe, dass es doch schneller ist. Ich werde nach einer Quelle suchen, um das zu belegen. Ich glaube, esdocument.write()
ist schnell, wenn Sie es verwenden, während die Seite bereits geöffnet ist.Hier ist Code, der document.write ersetzen soll:
document.write=function(s){ var scripts = document.getElementsByTagName('script'); var lastScript = scripts[scripts.length-1]; lastScript.insertAdjacentHTML("beforebegin", s); }
quelle
Lassen Sie hier nur eine Notiz fallen, um zu sagen, dass die Verwendung
document.write
aufgrund von Leistungsproblemen (synchrone DOM-Injektion und Auswertung) zwar stark verpönt ist , es jedoch auch keine tatsächliche 1: 1-Alternative gibt, wenn Siedocument.write
Skript-Tags bei Bedarf injizieren.Es gibt viele gute Möglichkeiten, dies zu vermeiden (z. B. Skriptlader wie RequireJS , die Ihre Abhängigkeitsketten verwalten), aber sie sind invasiver und werden daher am besten auf der gesamten Site / Anwendung verwendet.
quelle
Sie können die insertAdjacentHTML- Methode und document.currentScript kombinieren Eigenschaft .
Die
insertAdjacentHTML()
Methode der Element-Schnittstelle analysiert den angegebenen Text als HTML oder XML und fügt die resultierenden Knoten an einer bestimmten Position in den DOM-Baum ein :'beforebegin'
: Vor dem Element selbst.'afterbegin'
: Nur innerhalb des Elements, vor seinem ersten Kind.'beforeend'
: Nur innerhalb des Elements, nach seinem letzten Kind.'afterend'
: Nach dem Element selbst.Die
document.currentScript
Eigenschaft gibt das<script>
Element zurück, dessen Skript gerade verarbeitet wird. Die beste Position ist vor dem Start - neuer HTML- Code wird vor sich<script>
selbst eingefügt . Umdocument.write
dem nativen Verhalten zu entsprechen, würde man den Text nach dem Ende positionieren , aber dann werden die Knoten von aufeinanderfolgenden Aufrufen der Funktion nicht in der Reihenfolge platziert, in der Sie sie aufgerufen haben (wie dies derdocument.write
Fall ist), sondern in umgekehrter Reihenfolge. Die Reihenfolge, in der Ihr HTML angezeigt wird, ist wahrscheinlich wichtiger als die Position, in der sie relativ zum<script>
Tag platziert sind, daher die Verwendung von beforebegin .document.currentScript.insertAdjacentHTML( 'beforebegin', 'This is a document.write alternative' )
quelle
Die Frage hängt davon ab, was Sie tatsächlich versuchen.
Normalerweise anstatt das zu tun
document.write
können Sie verwenden ,someElement.innerHTML
oder besser,document.createElement
mit einemsomeElement.appendChild
.Sie können auch eine Bibliothek wie jQuery und die darin enthaltenen Änderungsfunktionen verwenden: http://api.jquery.com/category/manipulation/
quelle
Dies ist wahrscheinlich der korrekteste, direkteste Ersatz: insertAdjacentHTML .
quelle
Versuchen Sie, getElementById () oder getElementsByName () zu verwenden, um auf ein bestimmtes Element zuzugreifen, und verwenden Sie dann die innerHTML-Eigenschaft:
<html> <body> <div id="myDiv1"></div> <div id="myDiv2"></div> </body> <script type="text/javascript"> var myDiv1 = document.getElementById("myDiv1"); var myDiv2 = document.getElementById("myDiv2"); myDiv1.innerHTML = "<b>Content of 1st DIV</b>"; myDiv2.innerHTML = "<i>Content of second DIV element</i>"; </script> </html>
quelle
<\/b>
das Skript?Ich sehe das Problem nicht mit
document.write
. Wenn Sie es verwenden, bevor dasonload
Ereignis ausgelöst wird, wie Sie es vermutlich sind, um beispielsweise Elemente aus strukturierten Daten zu erstellen, ist es das geeignete Werkzeug. Die Verwendung bietet keinen LeistungsvorteilinsertAdjacentHTML
oder explizite Hinzufügung von Knoten zum DOM nach dessen Erstellung . Ich habe es gerade auf drei verschiedene Arten mit einem alten Skript getestet, mit dem ich einmal eingehende Modemanrufe für einen 24/7-Dienst auf einer Bank von 4 Modems geplant habe.Bis es fertig ist, erstellt dieses Skript über 3000 DOM-Knoten, hauptsächlich Tabellenzellen. Auf einem 7 Jahre alten PC, auf dem Firefox unter Vista ausgeführt wird, dauert diese kleine Übung weniger als 2 Sekunden,
document.write
wenn eine lokale 12-KB-Quelldatei und drei 1px-GIFs verwendet werden, die etwa 2000 Mal wiederverwendet werden. Die Seite wird nur vollständig erstellt und ist bereit, Ereignisse zu verarbeiten.Die Verwendung
insertAdjacentHTML
ist kein direkter Ersatz, da der Browser Tags schließt, für die das Skript geöffnet bleiben muss, und doppelt so lange dauert, bis eine verstümmelte Seite erstellt wird. Schreiben Sie alle Teile in eine Zeichenfolge und übergeben Sie sie dann aninsertAdjacentHTML
dauert noch länger, aber zumindest erhalten Sie die Seite wie geplant. Andere Optionen (wie das manuelle Neuerstellen des DOM für einen Knoten) sind so lächerlich, dass ich nicht einmal dorthin gehe.Manchmal
document.write
ist das Ding zu benutzen. Die Tatsache, dass es sich um eine der ältesten Methoden in JavaScript handelt, spricht nicht dagegen, sondern dafür - es handelt sich um hochoptimierten Code, der genau das tut, was er beabsichtigt hat und seit seiner Einführung getan hat.Es ist schön zu wissen, dass es alternative Nachlademethoden gibt, aber es muss verstanden werden, dass diese für einen ganz anderen Zweck bestimmt sind. Ändern des DOM, nachdem es erstellt und ihm Speicher zugewiesen wurde. Die Verwendung dieser Methoden ist von Natur aus ressourcenintensiver, wenn Ihr Skript den HTML-Code schreiben soll, aus dem der Browser das DOM erstellt.
Schreiben Sie es einfach und lassen Sie den Browser und den Dolmetscher die Arbeit erledigen. Dafür sind sie da.
PS: Ich habe gerade mit einem
onload
Parameter imbody
Tag getestet und selbst zu diesem Zeitpunkt ist das Dokument noch vorhandenopen
unddocument.write()
funktioniert wie beabsichtigt. Außerdem ist in der neuesten Version von Firefox kein Leistungsunterschied zwischen den verschiedenen Methoden erkennbar. Natürlich gibt es eine Menge Caching, das wahrscheinlich irgendwo im Hardware- / Software-Stack stattfindet, aber genau darum geht es - lassen Sie die Maschine die Arbeit erledigen. Auf einem billigen Smartphone kann dies jedoch einen Unterschied machen. Prost!quelle
Ich bin mir nicht sicher, ob das genau funktionieren wird, aber ich habe darüber nachgedacht
var docwrite = function(doc) { document.write(doc); };
Dies löste das Problem mit den Fehlermeldungen für mich.
quelle