jQuery document.createElement äquivalent?

1251

Ich überarbeite alten JavaScript-Code und es wird viel DOM manipuliert.

var d = document;
var odv = d.createElement("div");
odv.style.display = "none";
this.OuterDiv = odv;

var t = d.createElement("table");
t.cellSpacing = 0;
t.className = "text";
odv.appendChild(t);

Ich würde gerne wissen, ob es einen besseren Weg gibt, dies mit jQuery zu tun. Ich habe experimentiert mit:

var odv = $.create("div");
$.append(odv);
// And many more

Aber ich bin mir nicht sicher, ob das besser ist.

Rob Stevenson-Leggett
quelle
jsben.ch/#/ARUtz - ein Benchmark für jquery vs createElement
EscapeNetscape
Mögliches Duplikat des Erstellens eines div-Elements in jQuery
T.Todua
Nicht gefangener TypeError: $ .create ist keine Funktion
Tyguy7

Antworten:

1290

Hier ist Ihr Beispiel in der Zeile "Eins".

this.$OuterDiv = $('<div></div>')
    .hide()
    .append($('<table></table>')
        .attr({ cellSpacing : 0 })
        .addClass("text")
    )
;

Update : Ich dachte, ich würde diesen Beitrag aktualisieren, da er immer noch ziemlich viel Verkehr hat. In den Kommentaren unten wird über $("<div>")vs $("<div></div>")vs diskutiert, um $(document.createElement('div'))neue Elemente zu erstellen, und das ist "am besten".

Ich habe einen kleinen Benchmark zusammengestellt , und hier sind ungefähr die Ergebnisse der 100.000-maligen Wiederholung der oben genannten Optionen:

jQuery 1.4, 1.5, 1.6

               Chrome 11  Firefox 4   IE9
<div>            440ms      640ms    460ms
<div></div>      420ms      650ms    480ms
createElement    100ms      180ms    300ms

jQuery 1.3

                Chrome 11
<div>             770ms
<div></div>      3800ms
createElement     100ms

jQuery 1.2

                Chrome 11
<div>            3500ms
<div></div>      3500ms
createElement     100ms

Ich denke, es ist keine große Überraschung, aber es document.createElementist die schnellste Methode. Denken Sie natürlich daran, dass die Unterschiede, über die wir hier sprechen (mit Ausnahme der archaischen Versionen von jQuery), etwa 3 Millisekunden pro tausend Elemente entsprechen , bevor Sie mit der Überarbeitung Ihrer gesamten Codebasis beginnen .


Update 2

Aktualisiert für jQuery 1.7.2 und setzen Sie den Benchmark, JSBen.chder wahrscheinlich etwas wissenschaftlicher ist als meine primitiven Benchmarks. Außerdem kann er jetzt Crowdsourcing-fähig sein!

http://jsben.ch/#/ARUtz

nickf
quelle
70
Sie werden feststellen, dass document.createElement viel schneller ist, als wenn jQuery Ihre HTML-Zeichenfolge in ein Element konvertiert. (Nur für den Fall, dass Sie den Drang haben, die Dinge effizienter zu gestalten)
Sugendran
25
Das gilt für jQuery <1.3. Ich glaube, es entspricht der Geschwindigkeit.
Rob Stevenson-Leggett
15
@ Kevin, das ist wahr, aber es bringt jQuery dazu, mehr Arbeit zu erledigen (es führt eine Regex durch, um das schließende Tag hinzuzufügen), daher bevorzuge ich die obige Methode. Außerdem unterscheidet es Ihren Code, $('div')der optisch sehr ähnlich ist, aber funktional voneinander abweicht.
Nickf
14
Also im Grunde wäre eine Kombination von @Sungendran & @nickf $(document.createElement('div'))und es sollte die schnellste sein?
Kolky
14
Ich denke, der "richtige" Weg ist $ ('<div />'), wobei IMO noch mehr "Bedeutung" hat, da es ziemlich offensichtlich ist, dass Sie einen Knoten erstellen. Das Schlimme ist, dass auf diese Weise die Syntaxhervorhebung in allen Editoren unterbrochen wird = (
Erik Escobedo
139

Durch einfaches Bereitstellen des HTML-Codes von Elementen, die Sie einem jQuery-Konstruktor hinzufügen möchten, $()wird ein jQuery-Objekt aus neu erstelltem HTML zurückgegeben, das mit der append()Methode von jQuery an das DOM angehängt werden kann.

Zum Beispiel:

var t = $("<table cellspacing='0' class='text'></table>");
$.append(t);

Sie können diese Tabelle dann programmgesteuert füllen, wenn Sie dies wünschen.

Auf diese Weise können Sie beliebiges HTML angeben, einschließlich Klassennamen oder anderer Attribute, die Sie möglicherweise prägnanter finden, als createElementAttribute wie cellSpacingund classNameüber JS zu verwenden und dann festzulegen .

Adam Bellaire
quelle
7
Möglicherweise war dies offensichtlich und wurde in Ihrem Beispiel angegeben. Das Erstellen eines jQuery-DOM-Elements mit der Syntax $ ("<Html-String>") kann jedoch nicht mit der nativen Methode <element> .appendChild oder ähnlichem an das DOM angehängt werden. Sie müssen die jQuery-Append-Methode verwenden.
Adam
4
$(htmlStr)wird implementiert als document.createElement("div").innerHTML = htmlStr. Mit anderen Worten, es wird der HTML-Parser des Browsers aufgerufen. Fehlerhaftes HTML bricht im IE anders als in anderen Browsern.
Matthew
2
@Adam jQuery-Objekte haben die getFunktion, die das native DOM-Element zurückgibt. (Ich weiß, dass dieses Thema alt ist, aber ich füge es als Referenz hinzu. ;-))
Constantino Tsarouhas
1
Wenn Sie Probleme mit der HTML-Zeichenfolge haben, versuchen Sie, sie mit jQuery.parseHTML
fguillen
1
@ Adam Oder, wenn es für Ihren Code-Fluss / Augen einfacher ist, können Sie tun[dom element].appendChild($('<html>')[0]);
ACK_stoverflow
49

Ich mache das so:

$('<div/>',{
    text: 'Div text',
    class: 'className'
}).appendTo('#parentDiv');
Kami
quelle
44

da die jQuery1.8Verwendung $.parseHTML()zum Erstellen von Elementen eine bessere Wahl ist.

Es gibt zwei Vorteile:

1.Wenn Sie den alten Weg verwenden, der etwa so aussieht $(string), überprüft jQuery die Zeichenfolge, um sicherzustellen, dass Sie ein HTML-Tag auswählen oder ein neues Element erstellen möchten. Mit verwenden $.parseHTML()Sie jQuery, dass Sie explizit ein neues Element erstellen möchten, damit die Leistung möglicherweise etwas besser ist.

2. Viel wichtiger ist, dass Sie unter Cross-Site-Angriffen leiden können ( weitere Informationen ), wenn Sie den alten Weg verwenden. wenn du so etwas hast wie:

    var userInput = window.prompt("please enter selector");
    $(userInput).hide();

Ein Bösewicht kann etwas eingeben <script src="xss-attach.js"></script>, um dich zu ärgern. $.parseHTML()Vermeiden Sie zum Glück diese Verlegenheit für Sie:

var a = $('<div>')
// a is [<div>​</div>​]
var b = $.parseHTML('<div>')
// b is [<div>​</div>​]
$('<script src="xss-attach.js"></script>')
// jQuery returns [<script src=​"xss-attach.js">​</script>​]
$.parseHTML('<script src="xss-attach.js"></script>')
// jQuery returns []

Beachten Sie jedoch, dass aes sich um ein jQuery-Objekt handelt, während bes sich um ein HTML-Element handelt:

a.html('123')
// [<div>​123​</div>​]
b.html('123')
// TypeError: Object [object HTMLDivElement] has no method 'html'
$(b).html('123')
// [<div>​123​</div>​]
Brian
quelle
"Bessere Wahl" für "jedes Element erstellen" könnte stark sein. Die Antwort von @ siergiej sagt, dass parseHTMLes gut für HTML ist, das aus externen Quellen stammt, aber dass "der ganze Schub weg ist, nachdem die Ergebnisse in ein neues jQuery-Objekt verpackt wurden ". Das heißt, wenn Sie die Erstellung eines neuen, in jQuery eingeschlossenen HTML-Elements fest codieren möchten, $("<div>stuff</div>")scheint der Stil immer noch zu gewinnen.
Ruffin
38

AKTUALISIEREN

Ab den neuesten Versionen von jQuery weist die folgende Methode keine Eigenschaften zu, die im zweiten Objekt übergeben wurden

Vorherige Antwort

Ich fühle mich document.createElement('div')zusammen mit jQueryist schneller:

$(document.createElement('div'), {
    text: 'Div text',
    'class': 'className'
}).appendTo('#parentDiv');
Om Shankar
quelle
29

Obwohl dies eine sehr alte Frage ist, dachte ich, es wäre schön, sie mit aktuellen Informationen zu aktualisieren.

Seit jQuery 1.8 gibt es eine jQuery.parseHTML () -Funktion, die jetzt eine bevorzugte Methode zum Erstellen von Elementen ist. Außerdem gibt es einige Probleme beim Parsen von HTML über eine $('(html code goes here)')offizielle jQuery-Website, auf der beispielsweise in einem ihrer Versionshinweise Folgendes erwähnt wird :

Entspanntes HTML-Parsen: Vor Tags in $ (htmlString) können wieder führende Leerzeichen oder Zeilenumbrüche stehen. Wir empfehlen weiterhin dringend, dass Sie $ .parseHTML () verwenden, wenn Sie HTML analysieren, das aus externen Quellen stammt, und möglicherweise in Zukunft weitere Änderungen an der HTML-Analyse vornehmen.

Um sich auf die eigentliche Frage zu beziehen, könnte das bereitgestellte Beispiel übersetzt werden in:

this.$OuterDiv = $($.parseHTML('<div></div>'))
    .hide()
    .append($($.parseHTML('<table></table>'))
        .attr({ cellSpacing : 0 })
        .addClass("text")
    )
;

Dies ist leider weniger bequem als die Verwendung von nur $(), bietet Ihnen jedoch mehr Kontrolle. Sie können beispielsweise Skript-Tags ausschließen (es bleiben jedoch Inline-Skripte wie folgt onclick):

> $.parseHTML('<div onclick="a"></div><script></script>')
[<div onclick=​"a">​</div>​]

> $.parseHTML('<div onclick="a"></div><script></script>', document, true)
[<div onclick=​"a">​</div>​, <script>​</script>​]

Hier ist auch ein Benchmark aus der Top-Antwort, angepasst an die neue Realität:

JSbin Link

jQuery 1.9.1

  $ .parseHTML: 88 ms
  $ ($. parseHTML): 240 ms
  <div> </ div>: 138 ms
  <div>: 143 ms
  createElement: 64 ms

Es sieht so aus, als wäre parseHTMLes viel näher createElementals $(), aber der ganze Boost ist weg, nachdem die Ergebnisse in ein neues jQuery-Objekt eingeschlossen wurden

siergiej
quelle
11
var mydiv = $('<div />') // also works
Shimon Doodkin
quelle
6
var div = $('<div/>');
div.append('Hello World!');

Ist der kürzeste / einfachste Weg, um ein DIV-Element in jQuery zu erstellen.

AcidicChip
quelle
5

Ich habe gerade ein kleines jQuery-Plugin dafür erstellt: https://github.com/ern0/jquery.create

Es folgt Ihrer Syntax:

var myDiv = $.create("div");

Die DOM-Knoten-ID kann als zweiter Parameter angegeben werden:

var secondItem = $.create("div","item2");

Ist es ernst? Nein. Aber diese Syntax ist besser als $ ("<div> </ div>") und bietet ein sehr gutes Preis-Leistungs-Verhältnis.

Ich bin ein neuer jQuery-Benutzer, der von DOMAssistant wechselt und eine ähnliche Funktion hat: http://www.domassistant.com/documentation/DOMAssistantContent-module.php

Mein Plugin ist einfacher, ich denke, Attrs und Inhalte lassen sich besser durch Verkettungsmethoden hinzufügen:

$("#container").append( $.create("div").addClass("box").html("Hello, world!") );

Es ist auch ein gutes Beispiel für ein einfaches jQuery-Plugin (das 100.).

ern0
quelle
4

Es ist alles ziemlich einfach! Hier ein paar kurze Beispiele ...


var $example = $( XMLDocRoot );

var $element = $( $example[0].createElement('tag') );
// Note the [0], which is the root

$element.attr({
id: '1',
hello: 'world'
});

var $example.find('parent > child').append( $element );
Geil
quelle
1

In früheren Antworten nicht erwähnt, daher füge ich ein Arbeitsbeispiel zum Erstellen von Elementelementen mit der neuesten jQuery hinzu, auch mit zusätzlichen Attributen wie Inhalt, Klasse oder Onclick-Rückruf:

const mountpoint = 'https://jsonplaceholder.typicode.com/users'

const $button = $('button')
const $tbody = $('tbody')

const loadAndRender = () => {
  $.getJSON(mountpoint).then(data => {

    $.each(data, (index, { id, username, name, email }) => {
      let row = $('<tr>')
        .append($('<td>', { text: id }))
        .append($('<td>', {
          text: username,
          class: 'click-me',
          on: {
            click: _ => {
              console.log(name)
            }
          }
        }))
        .append($('<td>', { text: email }))

      $tbody.append(row)
    })

  })
}

$button.on('click', loadAndRender)
.click-me {
  background-color: lightgrey
}
<table style="width: 100%">
  <thead>
    <tr>
      <th>ID</th>
      <th>Username</th>
      <th>Email</th>
    </tr>
  </thead>
  <tbody>
  
  </tbody>
</table>

<button>Load and render</button>

<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>

Vladislav Ladicky
quelle
-2

jQuery out of the box entspricht nicht einem createElement. Tatsächlich wird der Großteil der Arbeit von jQuery intern mit innerHTML über reine DOM-Manipulation erledigt. Wie Adam oben erwähnt hat, können Sie auf diese Weise ähnliche Ergebnisse erzielen.

Es gibt auch Plugins, die das DOM über innerHTML verwenden, wie appendDOM , DOMEC und FlyDOM, um nur einige zu nennen. In Bezug auf die Leistung ist die native Abfrage immer noch die leistungsfähigste (hauptsächlich, weil sie innerHTML verwendet).

James Hughes
quelle
5
Sie sollten auf dem Laufenden bleiben. jQuery verwendet nicht innerHtml, sondern analysiert die HTML-Zeichenfolge und erstellt intern einen DOM-Baum mit document.createElement (). Dies ist der Kern von jQuery.
Vincent Robert