2014-09-07 29 views
6

Wszyscy wiedzą, co robią selektory DOM, takie jak document.getElementByID(...) i document.querySelector(...) i jak można z nich korzystać przy użyciu klas, atrybutów, identyfikatorów i tak dalej.W jaki sposób querySelector działa pod maską?

Ale nie byłem w stanie stwierdzić, jak działa pod maską (mogę znaleźć perf test comparisons, ale jestem zainteresowany teorią). Wiem, że strona html jest ładowana, analizowana przez przeglądarkę i tworzone jest drzewo DOM. Ale w jaki sposób każdy z selektorów przechodzi przez drzewo DOM, aby znaleźć elementy.

Ja wziąłem spojrzenie na spec for parsing algorithm i czytać naprawdę ładne explanation how Browsers work, ale również daje doskonałe wyjaśnienie na temat HTML, CSS analizowania i renderowania przepływ nie daje wyjaśnienie w jaki sposób każdy z tych selektorów przemierza tego drzewa, aby znaleźć elementy.

Zakładam, że w celu znalezienia czegoś podobnego .black lub span musi przechodzić przez całe drzewo, ale znaleźć #id można przejeżdżające jakąś dodatkową strukturę danych, a tym samym czyniąc go znacznie szybciej. Proszę nie pisać swoich założeń, szukam konkretnej wiedzy z backupem do specyfikacji lub implementacji w niektórych przeglądarkach.

+0

Myślę, że lepiej byłoby zapytać na stronie http://programmers.stackexchange.com – spender

+7

To szczegół implementacji i zależy od używanego silnika. Będziesz musiał przeczytać kod źródłowy różnych implementacji, jeśli chcesz wiedzieć. Zobacz http://pl.wikipedia.org/wiki/List_of_ECMAScript_engines jako punkt wyjścia. – slashingweapon

+0

@slashingweapon Tak naprawdę nie sądzę. Jest to dość podstawowa funkcja i najprawdopodobniej będę zaimplementowana bardzo podobnie w głównych przeglądarkach. –

Odpowiedz

6

Sprawdzanie Firefox's source i czytanie the related documentation pomoże uzyskać wstępny wgląd.
Po pobraniu dokumentu jest on przekazywany do analizatora składni (zobacz: /mozilla/parser/html/), który przeszukuje dokument i generuje drzewo zawartości. Centralne części analizatora składni są napisane w języku Java (/mozilla/parser/html/javasrc/), a następnie przetłumaczone na C++ dla budowania, więc przygotuj się na dobrą zabawę, jeśli chcesz przeczytać resztę źródła.

Patrząc na źródło parser'S (/mozilla/parser/html/javasrc/TreeBuilder.java), a mianowicie fragment funkcji 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   } 

Zwracając uwagę na linii 1590 i pamiętając, że wcześniej w tym samym pliku mamy:

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

Widzimy, że identyfikatory węzłów są przechowywane na prostej mapie skrótów. Sprawdzanie, w jaki sposób przetwarzane są zajęcia, jest ćwiczeniem pozostawionym czytelnikowi.

Różne metody DOM, na przykład document.getElementByID(...), są połączone z tą mapą skrótów za pomocą kodu kleju i mnogością hierarchii obiektów, patrz "How is the web-exposed DOM implemented?" on ask.mozilla.org.

+2

Doskonała odpowiedź !! –

Powiązane problemy