2014-09-07 15 views
6

Jeder weiß, was DOM Selektoren wie document.getElementByID(...) und document.querySelector(...) tun und wie Sie es mit Klassen, Attributen, ID und so weiter verwenden können.Wie funktioniert querySelector unter der Haube?

Aber ich konnte nicht finden, wie es unter der Haube funktioniert (ich kann perf test comparisons finden, aber ich interessiere mich für die Theorie). Ich weiß, dass die HTML-Seite geladen ist, vom Browser analysiert und die DOM-Struktur erstellt wird. Aber wie durchläuft jeder der Selektoren den DOM-Baum, um die Elemente zu finden.

Ich habe in einem spec for parsing algorithm einen Blick nahm und wirklich schön explanation how Browsers work, lesen, aber es gibt auch ausgezeichnete Erklärung über HTML, CSS Parsen und fließen wodurch es nicht Erklärung nicht geben, wie jeder dieser Selektoren diesen Baum durchläuft die Elemente zu finden.

Ich gehe davon aus, dass es so etwas wie .black oder span finden muss zu durchqueren den ganzen Baum in Ordnung, aber #id finden es einige zusätzliche Datenstruktur durchlaufen und somit kann es viel schneller. Bitte schreibe deine Annahmen nicht, ich suche nach konkreten Kenntnissen mit Backup zur Spezifikation oder Implementierung in manchen Browsern.

+0

Ich denke, das wäre besser bei http://programmers.stackexchange.com – spender

+7

Das ist ein Implementierungsdetail, und wird von der Maschine, die Sie verwenden, variieren. Sie müssen den Quellcode verschiedener Implementierungen lesen, wenn Sie das wissen wollen. Siehe http://en.wikipedia.org/wiki/List_of_ECMAScript_engines als Ausgangspunkt. – slashingweapon

+0

@slashingweapon Ich denke nicht wirklich so. Dies ist ein ziemlich grundlegendes Feature und wahrscheinlich werde ich in den meisten Browsern sehr ähnlich umgesetzt. –

Antwort

6

Die Überprüfung Firefox's source und das Lesen the related documentation helfen, erste Einsichten zu erhalten.
Sobald das Dokument abgerufen wurde, wird es an den Parser übergeben (siehe: /mozilla/parser/html/), der das Dokument durchkauen und einen Inhaltsbaum erzeugen wird. Die zentralen Teile des Parsers werden in Java geschrieben (/mozilla/parser/html/javasrc/) und dann zum Bauen in C++ übersetzt. Seien Sie also bereit, eine gute Zeit zu haben, wenn Sie den Rest der Quelle lesen wollen.

an der Quelle des Parsers sucht (/mozilla/parser/html/javasrc/TreeBuilder.java), nämlich ein Auszug aus der Funktion startTag:

1579   if (errorHandler != null) { 
1580    // ID uniqueness 
1581    @IdType String id = attributes.getId(); 
1582    if (id != null) { 
1583     LocatorImpl oldLoc = idLocations.get(id); 
1584     if (oldLoc != null) { 
1585      err("Duplicate ID \u201C" + id + "\u201D."); 
1586      errorHandler.warning(new SAXParseException(
1587        "The first occurrence of ID \u201C" + id 
1588        + "\u201D was here.", oldLoc)); 
1589     } else { 
1590      idLocations.put(id, new LocatorImpl(tokenizer)); 
1591     } 
1592    } 
1593   } 

Drehen Aufmerksamkeit auf Linie 1590 und unter Berücksichtigung der Tatsache, dass früher in der gleichen Datei, die wir haben:

459  private final Map<String, LocatorImpl> idLocations = new HashMap<String, LocatorImpl>(); 

Wir können sehen, dass Knoten IDs in einer einfachen Hash-Karte gehalten werden. Nachschlagen, wie Klassen verarbeitet werden, bleibt dem Leser überlassen.

Verschiedene DOME Methoden, beispielsweise document.getElementByID(...), sind mit dieser Hash-Karte durch die Glue-Code und eine Vielzahl von Objekthierarchie finden "How is the web-exposed DOM implemented?" on ask.mozilla.org.

+2

Ausgezeichnete Antwort !! –