effizienteste Methode zum iterieren über alle DOM-Elemente?

Leider brauche ich für die Iteration über die DOM-Elemente einer Seite und ich Frage mich, was die effizienteste Technik ist. Ich könnte wahrscheinlich benchmark diese selber und könnte, wenn ich die Zeit habe, aber ich bin der Hoffnung, jemand hat bereits erlebt, oder hat einige Optionen, die ich hatte nicht darüber nachgedacht.

derzeit bin ich mit jQuery und dies zu tun:

$('body *').each(function(){                                                                                                                            
      var $this = $(this);                                                                                                                                
      //do stuff                                                                                                                                         
});

Während es funktioniert, Es zu verursachen scheint einigen Verzögerungen auf dem client. Es könnte auch optimiert werden mit mehr spezifischen jQuery Kontext wie $('body', '*')
Es fiel mir ein, dass native javascript ist in der Regel schneller als jQuery und ich fand diese.

var items = document.getElementsByTagName("*");
    for (var i = 0; i < items.length; i++) {
        //do stuff
    }

Ich gehe davon aus, dass die native option ist schneller. Frage mich, ob es gibt andere Optionen, die ich hatte nicht darüber nachgedacht. Vielleicht eine rekursive option, iteriert über die Kind-Knoten parallel.

  • Ja, die Vanille-DOM Weg schneller ist. Aber warum müssen Sie die Iteration über alle Elemente?
  • cache der Elemente.Länge, so bist du nicht berechnend es jede iteration der Schleife, aber ja, die for-Schleife mit DOM-aufrufen werden, schneller als .jeder
  • Es sollte nicht sein, die einen spürbaren performance-Unterschied. jQuery verwenden querySelectorAll oder etwas, vorausgesetzt, dass der zur Verfügung. Einige subselector Situationen könnte es nicht verwenden, um nicht-native Methoden, wenn Sie können, aber ich glaube nicht, dass dies ist einer von Ihnen, und als Sie festgestellt haben, können Sie code, um sicherzustellen, dass es ohnehin tut. Zwar gibt es einige zusätzlichen Aufwand, es wird nicht materielles im Vergleich zu dem, was Sie bereits tut (die Schleife durch jedes element) in beiden Situationen. Ich würde stick mit jQuery, es sei denn, Sie wirklich nicht egal, wenn es funktioniert in älteren IE-Browser.
  • element.getElementsByTagName('*') funktioniert im IE6, die alle von jQuery unterstützt, so weit zurück als gut.
  • Aus Interesse, warum braucht man es überhaupt zu tun?
  • jeden Tag etwas neues lernen, für einige Grund, warum ich dachte, es war gebrochen IE6. Aber sieht aus wie du Recht hast.
  • Auch jQuery kann nicht optimieren "body *" sehr gut. Er tut große mit nur "Körper", sondern Sie verwenden Sie die "Körper *" es nutzt brutzeln JS. Das heißt, er will schließlich am Ende aufrufen document.querySelectorAll('body *'), aber es hat über 200 Zeilen Javascript-code zuerst, bevor Sie entscheidet zu tun, inklusive einer regex-test und andere Dinge. Das könnte nicht wie viel scheinen, aber es Vergleich zu document.body.getElementsByTagName('*') es eine Menge.
  • Bezüglich warum ich muss. Ich habe einen Fall, wo ich zu finden alle Elemente auf einer Seite, die die css-Attribut position:fixed und entsprechend zu handeln. Alles, was ich gefunden in Bezug auf diese wies bei der Iteration über jedes element. Ich könnte wahrscheinlich haben die Frage angesprochen, in Bezug auf oder stellen Sie eine eigene Frage für, die.
  • Eigentlich "body *" ist schneller (überrascht mich auch): jsperf.com/js-vs-jquery-select-all .. auch interessant, dass es einen Unterschied von etwa einer Größenordnung von 2 zwischen jQuery und die native Methode. Dies ist wahrscheinlich, weil jQuery durchläuft die gesamte Liste zu erstellen, die das Ergebnis intern festgelegt, und dann versuchen wir es noch einmal danach. In diesem Sinne, die DOM-Methode wäre schneller. Aber das hat zu tun mit ResultSet Gebäude und nicht brutzeln.
  • ist das wirklich alles, was Sie haben, mit zu arbeiten, die für dieses problem? Sie weiß nicht: alle Container, die die "festen" Dinge sein könnten, innerhalb, alle element-Typen (z.B. die wahrscheinlich nur div Elemente); Sie haben keine Möglichkeit zum zuweisen von Klassen oder sonst markieren Sie die Dinge, die Sie suchen, für andere als für einen Stil? Ist das ein real-Welt-situation oder ein hypothetisches problem?
  • Ich glaube, der Grund, warum Sie gefunden jQuery schneller sein wird da Sie document.querySelectorAll('*') statt document.querySelectorAll('body *') oder document.body.querySelectorAll('*'). Ich aktualisiert Ihre tests entsprechend: jsperf.com/js-vs-jquery-select-all/2
  • Ich glaube, Sie finden document.body.getElementsByTagName('*') ist die Schnellste. Ich bin mir nicht sicher, wie Sie Sie jsperf funktioniert zwar, aber ich glaube, da gibt es keinen body-tag in Ihre eingefügte HTML gibt es keine Treffer zu "body *", denn ich bin mir ziemlich sicher, dass es läuft im Fenster-Objekt.
  • du hast Recht (mein test war nicht fair), aber es war gebrochen, in der Gunst der Javascript-code. Ihre version verengt sich die Kluft. Es ist ein body-tag für die tests, die in der Beschreibung heißt es, die Inhalte werden in den Körper ein gültiges HTML5-Dokument. Aber ich denke, was die meisten wichtig zu beachten ist der Unterschied zwischen den verschiedenen jQuery Wege gehen, die Auswahl (und die js) - es ist ziemlich negligble, so cleary keiner von Ihnen ist mit brutzeln. Wenn das Zischen war invovled es wäre ein Faktor von mindestens 10 würde ich denken.
  • Ah, ich sehe, dass es eingefügt ist in ein body-tag jetzt. 🙂
  • Ich Schreibe an einem 3rd-party-Bibliothek enthalten ist, in die Benutzer-Seiten. Ich habe keine Ahnung, was Ihre Entwürfe oder markup Aussehen. Unsere Bibliothek injiziert einem festen element (einer Kopfzeile), die dazu führen können, überlappen sich mit Ihren Entwürfen. Um dies zu verhindern, bewegen wir uns alle von Ihrer position:fixed Elemente entsprechend. Die einzigen Dinge, die ich kann davon ausgehen, dass Sie vielleicht haben position:fixed Elemente innerhalb des body-Elements.
  • Es nutzt brutzeln obwohl (für die $('body *') Fall). Ich verwendet die unkomprimierte jQuery-Quelle mit einem Haltepunkt in der init-Funktion und dann lief es und fand, dass Sie ging in das Zischen, aber Sizzle ist geändert von jQuery, wenn if ( document.querySelectorAll ), so dass am Ende es endet nur mit context.querySelectorAll(query) (wo Kontext - = = = - Dokument und query = = = " Körper -*').
  • Was ich meine, ist es nicht wirklich nutzen brutzeln, die zum Durchlaufen des dom. Sicher - es ist mehr Aufwand - eine Menge von Zeilen von code in jQuery, das gleiche zu tun. Aber das ist nichts im Vergleich zu der Zeit, die Sie verbringen, Durchlaufen die Liste der Elemente und die überprüfung Klassen, das ist, was ich damit meine ist, vernachlässigbar.
  • elementFromPoint helfen könnte. Wenn es sicher davon ausgehen, dass die fixed-position-element werden die höchsten z-index (wenn nicht, gut, das ist einfach komisch), und Sie können ein paar andere grundlegende Annahmen über eine minimale Größe der festen element (e.g, es ist mindestens 10 Pixel hoch und 50 Pixel breit) könnte man leicht in einer Schleife durch ein Gitter in den Bereich, den Sie beabsichtigen zu besetzen, und aktivieren Sie nur die Stile, die die einzigartigen Elemente, die Sie finden unter den einzelnen Punkten in diesem Gitter. Sie würden laufen, eine native JS-Methode nicht mehr als (ich glaube) ein paar Dutzend mal, wahrscheinlich viel schneller als die Auswahl esp (mit IE6)
  • Mögliche Duplikate von: Wie eine Schleife durch ALLE DOM-Elemente auf einer Seite?
  • überprüfen Sie das benchmark jsben.ch/#/Ro9H6

InformationsquelleAutor kevzettler | 2012-01-05
Schreibe einen Kommentar