jQuery, das ein Array von Elementen anhängt

Lesezeit: 3 Minuten

Benutzer-Avatar
Georg Reith

Nehmen wir zum Zweck dieser Frage an, wir müssen append() 1000 Objekte zum body Element.

Du könntest so vorgehen:

for(x = 0; x < 1000; x++) {
    var element = $('<div>'+x+'</div>');
    $('body').append(element);
}

Dies funktioniert, erscheint mir jedoch ineffizient, da dies AFAIK zu 1000 Dokumentenumbrüchen führen wird. Eine bessere Lösung wäre:

var elements = [];
for(x = 0; x < 1000; x++) {
    var element = $('<div>'+x+'</div>');
    elements.push(element);
}
$('body').append(elements);

Dies ist jedoch keine ideale Welt, und dies wirft einen Fehler auf Could not convert JavaScript argument arg 0 [nsIDOMDocumentFragment.appendChild]. ich verstehe das append() kann nicht mit Arrays umgehen.

Wie würde ich verwenden jQuery (Ich kenne die DokumentFragment Knoten, aber nehme an, ich muss andere jQuery-Funktionen für das Element verwenden, z .css()) eine Reihe von Objekten auf einmal zum DOM hinzufügen, um die Leistung zu verbessern?

  • append() akzeptiert kein Array von Strings.

    – escarello

    24. August 2012 um 14:55 Uhr


  • @GeorgeReith Die von Ihnen genehmigte Antwort ist noch langsamer als Ihr erster Ansatz. Sehen Sie sich die Konsolenprotokolle in diesem jsfiddle an jsfiddle.net/du2TN/2

    – Davids

    24. August 2012 um 15:23 Uhr

  • @davids interessant, obwohl es scheint, dass mein ursprünglicher Code in jQuery 1.8 funktioniert und die schnellste der jQuery-Methoden ist. (aktualisiert Ihr JSfiddle)

    – Georg Reith

    24. August 2012 um 15:29 Uhr


  • Gut zu wissen 🙂 Wie auch immer, die Lösung von @jAndi und Jackwander ist viel schneller. Aber wenn Sie lieber jQuery verwenden, was auch immer zu Ihnen passt 🙂

    – Davids

    24. August 2012 um 15:35 Uhr

  • @davids Ich muss jQuery verwenden, da es sich um jQuery-Objekte handeln muss, damit ich andere jQuery-Funktionen darin verwenden kann.

    – Georg Reith

    24. August 2012 um 16:57 Uhr

Benutzer-Avatar
Felix Klinge

Sie könnten anstelle eines Arrays ein leeres jQuery-Objekt verwenden:

var elements = $();
for(x = 0; x < 1000; x++) {
    elements = elements.add('<div>'+x+'</div>');
    // or 
    // var element = $('<div>'+x+'</div>');
    // elements = elements.add(element);
}
$('body').append(elements);

Dies kann nützlich sein, wenn Sie Dinge mit neu generierten Elementen innerhalb der Schleife tun möchten. Beachten Sie jedoch, dass dadurch ein riesiger interner Stapel von Elementen (innerhalb des jQuery-Objekts) erstellt wird.


Es scheint aber so Ihr Code funktioniert einwandfrei mit jQuery 1.8.

  • Meine eigentliche Testlösung ist etwas komplizierter, jedes Element sollte ein eigenständiges jQuery-Objekt sein, damit Sie andere jQuery-Funktionen darauf ausführen können. Mein Fehler, weil ich den Testfall zu sehr vereinfacht habe. Aktualisierte Frage, um dies widerzuspiegeln.

    – Georg Reith

    24. August 2012 um 14:58 Uhr


  • Aber dann mit .add und das Einfügen des endgültigen jQuery-Objekts sollte trotzdem funktionieren.

    – Felix Klinge

    24. August 2012 um 14:59 Uhr

  • Ups du hast recht, das hatte ich vergessen add aktualisiert die Originalkopie nicht.

    – Georg Reith

    24. August 2012 um 15:02 Uhr

  • @George: Anscheinend die .append Verhalten geändert mit jQuery 1.8. Es funktioniert jetzt auch mit Arrays von jQuery-Objekten. Das ist dein Code: jsfiddle.net/7Q6wm/2. Ich nehme an, Sie haben eine ältere Version verwendet.

    – Felix Klinge

    24. August 2012 um 15:15 Uhr

  • in älteren Versionen von jQuery nicht funktioniert, verwenden Sie die Methode document.createDocumentFragment, die von @jackwanders beschrieben wird

    – Scott Jungwirth

    20. Oktober 2015 um 20:55 Uhr


Benutzer-Avatar
jAndy

Du könntest einfach anrufen

$('body').append(elements.join(''));

Oder Sie können erst einmal eine große Zeichenfolge erstellen.

var elements="";
for(x = 0; x < 1000; x++) {
    elements = elements + '<div>'+x+'</div>';
}
$(document.body).append(elements);

Wie Sie bereits erwähnt haben, ist der wahrscheinlich “richtigste” Weg die Verwendung eines DocFrag. So könnte es aussehen

var elements = document.createDocumentFragment(),
    newDiv;
for(x = 0; x < 1000; x++) {
    newDiv = document.createElement('div');
    newDiv.textContent = x;
    elements.append( newDiv );
}
$(document.body).append(elements);

.textContent wird von IE<9 nicht unterstützt und würde zur Verwendung eine bedingte Prüfung erfordern .innerText oder .text stattdessen.

  • @JosephSilber: nichts falsch mit der Verwendung += Natürlich. Ich wollte hier nur expliziter und ausdrucksvoller sein.

    – jAndy

    24. August 2012 um 14:58 Uhr

  • Danke Andy, aber ich fürchte, ich habe meinen Testfall zu stark vereinfacht (mein Fehler), ich sollte jedes Element zu einem eigenen Objekt machen, damit Sie jQuery-Funktionen wie ausführen können .css() auf sie. Ich habe den Testfall in der Frage aktualisiert.

    – Georg Reith

    24. August 2012 um 14:59 Uhr


  • Sollte das nicht sein newDiv.textContent = x;?

    – Josef Silber

    24. August 2012 um 15:09 Uhr

Upgrade auf jQuery 1.8, das funktioniert wie vorgesehen:

​$('body')​.append([
    '<b>1</b>',
    '<i>2</i>'   
])​;​

Da $.fn.append eine variable Anzahl von Elementen benötigt, können wir sie verwenden apply um das Array als Argumente zu übergeben:

el.append.apply(el, myArray);

Dies funktioniert, wenn Sie ein Array von jQuery-Objekten haben. Gemäß der Spezifikation können Sie jedoch ein Array von Elementen anhängen, wenn Sie die DOM-Elemente haben. Wenn Sie ein Array von HTML-Strings haben, können Sie sie einfach .join(”) und alle auf einmal anhängen.

Eine kleine Änderung zu Ihrem zweiten Ansatz:

var elements = [],
newDiv;
for (x = 0; x < 1000; x++) {
    newDiv = $('<div/>').text(x);
    elements.push(newDiv);
}
$('body').append(elements);

$.append() kann sicherlich ein Array anhängen: http://api.jquery.com/append/

.append(Inhalt) | Inhalt: Ein oder mehrere zusätzliche DOM-Elemente, Arrays von Elementen, HTML-Strings oder jQuery-Objekte, die am Ende jedes Elements in den Satz übereinstimmender Elemente eingefügt werden.

  • jQuery war in dieser Hinsicht sehr streng. Wenn es “Array von Elementen” sagt, meint es wirklich DOM-Elemente, nicht jQuery-Objekte. Und tatsächlich, mit 1.7.2 funktioniert dieser Code nicht, aber er funktioniert in 1.8.

    – Felix Klinge

    24. August 2012 um 15:16 Uhr

Benutzer-Avatar
Jackwander

Manchmal ist jQuery nicht die beste Lösung. Wenn Sie viele Elemente an das DOM anhängen müssen, documentFragment ist eine gangbare Lösung:

var fragment = document.createDocumentFragment();
for(var i = 0; i < 1000; i++) {
    fragment.appendChild(document.createElement('div'));
}
document.getElementsByTagName('body')[0].appendChild(fragment);

  • jQuery war in dieser Hinsicht sehr streng. Wenn es “Array von Elementen” sagt, meint es wirklich DOM-Elemente, nicht jQuery-Objekte. Und tatsächlich, mit 1.7.2 funktioniert dieser Code nicht, aber er funktioniert in 1.8.

    – Felix Klinge

    24. August 2012 um 15:16 Uhr

Benutzer-Avatar
MalSu

Wenn Sie nach roher Leistung streben, würde ich reines JS vorschlagen, obwohl einige argumentieren würden, dass Ihre Entwicklungsleistung wichtiger ist als die Leistung Ihrer Website / Ihres Programms. Überprüfen Sie dies Verknüpfung für Benchmarks und eine Präsentation verschiedener DOM-Einfügungstechniken.

bearbeiten:

Als Kuriosum, documentFragment erweist sich als eine der langsamsten Methoden.

  • dass jsPerf umschließt documentFragment in einem $() anrufen, was ihn wahrscheinlich verlangsamt. documentFragment ist immer noch nützlich, wenn Sie sich für eine reine JS-Lösung entscheiden.

    – Jackwander

    24. August 2012 um 15:01 Uhr

  • Dieser Test ist eine seltsame Mischung aus DOM und jQuery, ich glaube nicht, dass er sehr schlüssig ist.

    – Felix Klinge

    24. August 2012 um 15:01 Uhr

  • Es verwendet jeweils jQuery, aber das eigentliche Anhängen erfolgt mit unterschiedlichen Methoden.

    – MalSu

    24. August 2012 um 15:03 Uhr

1287150cookie-checkjQuery, das ein Array von Elementen anhängt

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy