2010-01-30 3 views
11

Ich habe viele Elemente, die oft generiert und referenziert werden (Mouseover, Klicks, Positionsänderungen).Soll ich document.getElementById() in einer Variablen zwischenspeichern oder sie jedes Mal aufrufen?

Ich habe die IDs dieser Elemente zur Hand. Ist es klug, die document.getElementById(ID) Aufrufe in einer Variablen zu speichern, oder ist es schneller/genauso schnell/langsamer, document.getElementById() jedes Mal aufzurufen?

var app = []; 
var app.elements = []; 
//i can store ['id1', 'id2', 'id3'] 
//OR ['id1' => document.getElementById('id1'), 'id2' => document.getElementById('id2'), 'id3' => document.getElementById('id3')] 
+0

Weder - Sie sollten jQuery verwenden! – Aaronaught

+0

Ich benutze jQuery. Für Leistungssteigerungen: dieselbe Frage: sollte ich das jQuery-Objekt ($ ('# id1')) zwischenspeichern oder sollte ich $ ('# id1') jedes Mal aufrufen, wenn ich es brauche? – Ropstah

Antwort

8

Sie sollten die Referenz natürlich wo immer möglich wiederverwenden, aber Sie müssen möglicherweise eine neue Referenz in jedem Funktionskörper erhalten.

Beispiel:

var e1 = document.getElementById('id1'); 
e1.innerHTML = 'test'; 
e1.className = 'info'; 

Wenn Sie Referenzen halten länger, können Sie feststellen, dass sie nicht mehr funktionieren. Wenn Sie zum Beispiel innerHTML für einen Teil der Seite erhalten und es zurückspeichern, werden alle Elemente in diesem Teil entfernt und neu erstellt. Wenn Sie einen Verweis auf eines der Elemente in diesem Teil hatten, ist dieses Element nicht mehr vorhanden.

// This will recreate all elements inside the 'parent' element: 
document.getElementById('parent').innerHTML += 'test'; 
+0

Das ist ein guter Punkt, und ich möchte hinzufügen, dass Sie nie wissen, wer oder was einen DOM-Knoten unter Ihnen ändern wird. Ich bevorzuge es, den Verweis explizit zu erhalten, um Fehler zu reduzieren und die Lesbarkeit zu verbessern. Wenn Sie in einer Situation mit hoher Leistung viele Knoten verwalten, möchten Sie sie möglicherweise stattdessen dem Arbeitsspeicher zuweisen. –

+0

Es wird rund 500 Elemente sein, aber sie werden korrekt verwaltet. Ich benutze jQuery und die meiste Zeit wird das Objekt $ (jqueryfied) sein, so dass ich Funktionen wie position() aufrufen kann. Gilt das gleiche für das Speichern des $ ('# id1') Objekts im Speicher? – Ropstah

+0

Oh, jetzt macht es Sinn. Ich habe mich gefragt, warum Caching Funktionsaufrufe unterbricht. (Natürlich habe ich dort neue Elemente erschaffen). – Dallaylaen

2

Es ist sicherlich schneller, die Elemente in einer Variablen zu speichern, aber nicht mit einem großen Abstand. Dies unterscheidet sich von Fall zu Fall und sollte für jeden individuell angepasst werden.

Der vielleicht größte Faktor ist die Lesbarkeit. Ich glaube, dass der direkte Zugriff auf die Elemente besser lesbar ist.

+0

Ich bin auf der Suche nach Leistungssteigerungen hier. Der Code wird in Funktionen abgelegt und muss nicht gelesen werden :) – Ropstah

+2

ALLER Code muss gelesen werden, es sei denn, es wird beim ersten Mal perfekt geschrieben, muss nie geändert oder erweitert werden, benötigt nie neue Funktionen und muss nie verstanden werden . :) – Eddie

+0

Wäre es immer noch schneller, wenn Sie es in einem Sparse Array/Map speichern? Ich frage, weil getElementById im Wesentlichen bereits die IDs zwischengespeichert hat, also bin ich mir nicht sicher, ob es irgendwelche Vorteile für einen Cache der Elemente gibt, die bereits eine ID haben (schnellste Suche), die die Elemente speichert, vor denen Sie suchen würden Zeit, aber im Prozess des Nachschlagens der Daten tun Sie im Wesentlichen das Gleiche wie getElementById ... – Dmitry

3

getElementById gibt einen Elementknoten zurück, der im Wesentlichen nur ein JavaScript-Objekt ist. Sie können dieses Objekt einer Variablen zuweisen, was bedeutet, dass die Variable auf dieses Objekt zeigt, wenn Sie diese Variable zu einem späteren Zeitpunkt eingeben. So

var id1 = document.getElementById('id1'); 

id1 bezieht sich nun auf das DOM-Element mit einem id von id1. Wenn mit dem id kein Element gefunden wurde, gibt document.getElementById null zurück.

Wenn die Elemente innerhalb des DOM bleiben und nicht ersetzt werden, dann ist es sinnvoll, sie in einem Array zu speichern, so dass Sie so oft wie gewünscht ohne Leistungsaufwand referenzieren können.

Wenn es hilft, könnten Sie eine einfache Funktion schaffen es für Sie tun:

function getElementsByIds(/* id1, id2 ... */) { 

    var elems = []; 

    for (var i = 0, l = arguments.length; i < l; i++) { 
     elems[i] = document.getElementById(arguments[i]); 
    } 

    return elems; 

} 

app.elements = getElementsByIds('id1', 'id2', 'id3'); 
3

Es gibt keine einzige richtige Antwort auf diese Frage. Alles hängt davon ab, mit was Sie arbeiten müssen. Wenn Sie mit einer Seite arbeiten, die viele Elemente in der DOM-Struktur enthält, sollten Sie die Referenzen zwischenspeichern und wiederverwenden, um die Nachschlagezeit zu verkürzen. Wenn Sie an einer kleinen Seite arbeiten, ist es besser, Elemente im laufenden Betrieb nachzuschlagen und den Speicherverbrauch des Browsers zu minimieren.

Dies hängt auch von den Browsern ab, auf die Sie ausgerichtet sind. Zum Beispiel brauchen neuere Versionen von Firefox eine Weile, um ein Element zum ersten Mal zu korrigieren, aber sie cachen den Verweis intern, so dass das nächste Mal, wenn Sie nachsehen werden, es fast sofort sein wird. Auf der anderen Seite speichert IE keine Lookup-Werte, aber die Suchzeit ist beim ersten Versuch viel schneller als Firefox.

Viele moderne Frameworks werden die Elemente, die Sie für Sie gefunden haben, zwischenspeichern. Allerdings bevorzuge ich persönlich immer noch die Verwendung von document.getElementById die meiste Zeit.Was ich tun, wenn ich Lookup-Werte zwischenzuspeichern müssen, ist die folgende:

function registerElement(id) 
{ 
    if (!this["get_" + id]) 
     this["get_" + id] = function() { 
      var element = document.getElementById(id); 
      this["get_" + id] = function() {return element;}; 
      return element; 
     } 
} 

Sie verwenden diese durch registerElement Aufruf und eine ID des Elements vorbei. Wenn Sie den Wert abrufen müssen, rufen Sie die get_element-ID auf, die Sie übergeben haben, und beim ersten Ausführen wird das Element nachgeschlagen und zwischengespeichert. Bei jedem nachfolgenden Aufruf wird nur der zwischengespeicherte Wert zurückgegeben.

Verwandte Themen