Was sind in der Praxis die Vorteile von createElement gegenüber innerHTML? Ich frage, weil ich davon überzeugt bin, dass die Verwendung von innerHTML in Bezug auf Leistung und Lesbarkeit / Wartbarkeit von Code effizienter ist, aber meine Teamkollegen haben sich entschieden, createElement als Codierungsansatz zu verwenden. Ich möchte nur verstehen, wie createElement effizienter sein kann.
javascript
dom
innerhtml
createelement
oninea
quelle
quelle
Antworten:
Neben der Sicherheit gibt es neben der Sicherheit mehrere Vorteile, die Sie verwenden müssen,
createElement
anstatt sie zu modifiziereninnerHTML
( anstatt sie einfach wegzuwerfen und zu ersetzen), wie Pekka bereits erwähnt hat:Behält vorhandene Verweise auf DOM-Elemente beim Anhängen von Elementen bei
Wenn Sie an anhängen (oder auf andere Weise ändern)
innerHTML
, müssen alle DOM-Knoten in diesem Element neu analysiert und neu erstellt werden. Wenn Sie Verweise auf Knoten gespeichert haben, sind diese im Wesentlichen nutzlos, da sie nicht mehr angezeigt werden.Erhält Ereignishandler, die an DOM-Elemente angehängt sind
Dies ist wirklich nur ein Sonderfall (obwohl häufig) des letzten. Durch die Einstellung
innerHTML
werden Ereignishandler nicht automatisch wieder mit den neu erstellten Elementen verknüpft. Sie müssten sie daher selbst verfolgen und manuell hinzufügen. Durch die Ereignisdelegierung kann dieses Problem in einigen Fällen behoben werden.Könnte in einigen Fällen einfacher / schneller sein
Wenn Sie viele Ergänzungen
innerHTML
vornehmen, möchten Sie auf keinen Fall weiter zurücksetzen, da das wiederholte erneute Parsen und Erstellen von Elementen langsamer ist, obwohl dies für einfache Änderungen schneller ist. Der Weg, dies zu umgehen, besteht darin, den HTML-Code in einer Zeichenfolge aufzubauen undinnerHTML
einmal festzulegen, wenn Sie fertig sind. Je nach Situation kann die Zeichenfolgenmanipulation langsamer sein als nur das Erstellen und Anhängen von Elementen.Darüber hinaus kann der Code zur Manipulation von Zeichenfolgen komplizierter sein (insbesondere, wenn Sie möchten, dass er sicher ist).
Hier ist eine Funktion, die ich manchmal benutze, um sie bequemer zu machen
createElement
.function isArray(a) { return Object.prototype.toString.call(a) === "[object Array]"; } function make(desc) { if (!isArray(desc)) { return make.call(this, Array.prototype.slice.call(arguments)); } var name = desc[0]; var attributes = desc[1]; var el = document.createElement(name); var start = 1; if (typeof attributes === "object" && attributes !== null && !isArray(attributes)) { for (var attr in attributes) { el[attr] = attributes[attr]; } start = 2; } for (var i = start; i < desc.length; i++) { if (isArray(desc[i])) { el.appendChild(make(desc[i])); } else { el.appendChild(document.createTextNode(desc[i])); } } return el; }
Wenn Sie es so nennen:
make(["p", "Here is a ", ["a", { href:"http://www.google.com/" }, "link"], "."]);
Sie erhalten das Äquivalent dieses HTML:
<p>Here is a <a href="http://www.google.com/">link</a>.</p>
quelle
make
Funktion ein wenig einfacher machen kann).innerHTML
wegen seiner Nachteile. Bei komplexen Markups (wie dem Erstellen einer Tabelle) schreibe ich normalerweise Funktionen, um jeden Teil des Markups zu generieren. Zum Beispiel hätte ich eine Funktion, dietr
aus den Daten für jede Zeile ein generiert . Dann könnte ich eine andere Funktion haben, die die Zeilen zu einer Tabelle kombiniert. Jede Funktion kann so einfach sein wie das Aufrufenmake
mit den entsprechenden Argumenten. Sollte die Leistung jemals zu einem Problem werden, kann ich die Funktionen ändern, um HTML-Zeichenfolgen zurückzugeben.Obwohl
innerHTML
es schneller sein kann, stimme ich nicht zu, dass es in Bezug auf Lesbarkeit oder Wartung besser ist. Es kann kürzer sein, alles in eine Zeichenfolge zu setzen, aber kürzerer Code ist nicht immer notwendigerweise wartbarer.Die Verkettung von Zeichenfolgen lässt sich einfach nicht skalieren, wenn dynamische DOM-Elemente als Pluszeichen erstellt werden müssen und das Öffnen und Schließen von Anführungszeichen schwierig zu verfolgen ist. Betrachten Sie diese Beispiele:
Das resultierende Element ist ein Div mit zwei inneren Bereichen, deren Inhalt dynamisch ist. Einer der Klassennamen (Krieger) innerhalb der ersten Spanne ist ebenfalls dynamisch.
<div> <span class="person warrior">John Doe</span> <span class="time">30th May, 2010</span> </div>
Angenommen, die folgenden Variablen sind bereits definiert:
var personClass = 'warrior'; var personName = 'John Doe'; var date = '30th May, 2010';
Wenn wir nur innerHTML verwenden und alles zu einer einzigen Zeichenfolge zusammenfügen, erhalten wir:
someElement.innerHTML = "<div><span class='person " + personClass + "'>" + personName + "</span><span class='time'>" + date + "</span></div>";
Das obige Durcheinander kann durch Ersetzen von Saiten behoben werden, um zu vermeiden, dass Saiten jedes Mal geöffnet und geschlossen werden. Selbst für einfache Textersetzungen bevorzuge ich die Verwendung
replace
anstelle der Verkettung von Zeichenfolgen.Dies ist eine einfache Funktion, die ein Objekt aus Schlüsseln und Ersetzungswerten nimmt und diese in der Zeichenfolge ersetzt. Es wird davon ausgegangen, dass den Schlüsseln ein Präfix vorangestellt ist,
$
um anzuzeigen, dass es sich um einen speziellen Wert handelt. Es werden keine Flucht- oder Kantenfälle ausgeführt,$
die im Wiederbeschaffungswert usw. angegeben sind.function replaceAll(string, map) { for(key in map) { string = string.replace("$" + key, map[key]); } return string; } var string = '<div><span class="person $type">$name</span><span class="time">$date</span></div>'; var html = replaceAll(string, { type: personClass, name: personName, date: date }); someElement.innerHTML = html;
Dies kann verbessert werden, indem die Attribute, der Text usw. beim Erstellen des Objekts getrennt werden, um eine programmgesteuerte Kontrolle über die Elementkonstruktion zu erhalten. Mit MooTools können wir beispielsweise Objekteigenschaften als Karte übergeben. Dies ist sicherlich besser zu warten, und ich würde auch besser lesbar argumentieren. jQuery 1.4 verwendet eine ähnliche Syntax, um eine Zuordnung zum Initialisieren von DOM-Objekten zu übergeben.
var div = new Element('div'); var person = new Element('span', { 'class': 'person ' + personClass, 'text': personName }); var when = new Element('span', { 'class': 'time', 'text': date }); div.adopt([person, when]);
Ich würde den reinen DOM-Ansatz unten nicht als besser lesbar bezeichnen als den oben genannten, aber er ist sicherlich besser zu warten, da wir das Öffnen / Schließen von Anführungszeichen und zahlreiche Pluszeichen nicht im Auge behalten müssen.
var div = document.createElement('div'); var person = document.createElement('span'); person.className = 'person ' + personClass; person.appendChild(document.createTextNode(personName)); var when = document.createElement('span'); when.className = 'date'; when.appendChild(document.createTextNode(date)); div.appendChild(person); div.appendChild(when);
Die am besten lesbare Version würde sich höchstwahrscheinlich aus der Verwendung einer Art JavaScript-Vorlage ergeben .
<div id="personTemplate"> <span class="person <%= type %>"><%= name %></span> <span class="time"><%= date %></span> </div> var div = $("#personTemplate").create({ name: personName, type: personClass, date: date });
quelle
var a = hello
, aber ich kann Ihren Code herausfinden. Das sieht besser lesbar aus als eine einzelne verkettete Zeichenfolge.innerHTML
schneller ? Nicht nach jsperf.com/innerhtml-vs-createelement-and-appendchildUser Bobince bringt eine Reihe von Nachteilen sehr, sehr gut in seine Kritik an jQuery ein .
Was die Leistung
betrifft:InnerHTML wird definitiv langsamer sein, da es analysiert und intern in DOM-Elemente konvertiert werden muss (möglicherweise mithilfe dercreateElement
Methode).InnerHTML ist in allen Browsern gemäß dem von @Pointy bereitgestellten Quirksmode-Benchmark schneller.
Wie für die Lesbarkeit und Benutzerfreundlichkeit, finden Sie mir die Wahl
innerHTML
übercreateElement
in den meisten Projekten an jedem Tag der Woche. Aber wie Sie sehen, gibt es viele Punkte, für die gesprochen wirdcreateElement
.quelle
innerHTML
, langsamer zu sein? Ich weiß, dass das lange Zeit definitiv falsch war.innerHTML
Tatsächlich wurde die Verwendung in Frameworks gerade wegen des dramatischen Leistungsvorteils in einigen Browsern populär (raten Sie mal).createElement
im ersten Schritt tut. Wenn Sie jedoch Benchmarks kennen, die etwas anderes aussagen, stehe ich gerne korrigiert da.Sie sollten createElement verwenden, wenn Sie Referenzen in Ihrem Code behalten möchten. InnerHTML kann manchmal einen Fehler verursachen, der schwer zu erkennen ist.
HTML Quelltext:
<p id="parent">sample <span id='test'>text</span> about anything</p>
JS-Code:
var test = document.getElementById("test"); test.style.color = "red"; //1 - it works document.getElementById("parent").innerHTML += "whatever"; test.style.color = "green"; //2 - oooops
1) Sie können die Farbe ändern
2) Sie können die Farbe oder was auch immer nicht mehr ändern, da Sie in der obigen Zeile etwas zu innerHTML hinzugefügt haben und alles neu erstellt wurde und Sie Zugriff auf etwas haben, das nicht mehr existiert. Um es zu ändern, müssen Sie erneut GetElementById erhalten .
Sie müssen sich daran erinnern, dass dies auch alle Ereignisse betrifft. Sie müssen Ereignisse erneut anwenden.
InnerHTML ist großartig, weil es schneller und meistens einfacher zu lesen ist, aber Sie müssen vorsichtig sein und es mit Vorsicht verwenden. Wenn Sie wissen, was Sie tun, werden Sie in Ordnung sein.
quelle
Vorlagenliterale (Vorlagenzeichenfolgen) sind eine weitere Option.
const container = document.getElementById("container"); const item_value = "some Value"; const item = `<div>${item_value}</div>` container.innerHTML = item;
quelle