2014-09-07 10 views
6

document.getElementByID(...)document.querySelector(...)과 같은 DOM 선택기는 누구나 알고 있으며 클래스, 속성, ID 등과 함께 사용할 수있는 방법을 알고 있습니다.후드에서 querySelector는 어떻게 작동합니까?

하지만 두포에서 어떻게 작동하는지 찾을 수 없었습니다 (나는 perf test comparisons을 찾을 수 있지만 이론에 관심이 있습니다). html 페이지가 브라우저에서 파싱되어로드되고 DOM 트리가 구성된다는 것을 알고 있습니다. 하지만 각 선택기는 요소를 찾기 위해 DOM 트리를 어떻게 지나치 는가?

나는 spec for parsing algorithm을보고 실제로는 explanation how Browsers work을 읽었지만, HTML, CSS 파싱 및 렌더링 흐름에 대한 훌륭한 설명을 제공합니다.이 선택기가이 트리를 통과하여 요소를 찾는 방식을 설명하지 않습니다.

나는 .black 또는 span 뭔가를 찾기 위해이 전체 트리를 통과 할 수 있지만, 훨씬 빠르게 그것을 만드는 몇 가지 추가 데이터 구조를 통과함으로써 할 수있다 #id을 찾을 필요가 있다고 가정합니다. 귀하의 가정을 쓰지 말고, 일부 브라우저의 사양이나 구현에 대한 구체적인 지식을 찾고 있습니다.

+0

나는 이것이 http://programmers.stackexchange.com – spender

+7

에 더 잘 어울릴 것이라고 생각합니다. 구현 세부 사항이며 사용중인 엔진에 따라 다릅니다. 알고 싶으면 다양한 구현의 소스 코드를 읽어야합니다. http://en.wikipedia.org/wiki/List_of_ECMAScript_engines를 참조하십시오. – slashingweapon

+0

@slashingweapon 나는 그렇게 생각하지 않는다. 이것은 아주 기본적인 기능이며, 아마도 주요 브라우저에서 실제로 구현 될 것입니다. –

답변

6

Firefox's source을 검사하고 the related documentation을 읽으면 몇 가지 초기 통찰력을 얻을 수 있습니다.
문서를 가져 오면 파서 (문서 : /mozilla/parser/html/ 참조)로 전달되어 문서를 씹어보고 내용 트리를 생성합니다. 파서의 중심 부분은 Java (/mozilla/parser/html/javasrc/)로 작성된 후 C++로 변환하기 때문에 소스의 나머지 부분을 읽고 싶을 때가 있습니다. 파서의 소스 (/mozilla/parser/html/javasrc/TreeBuilder.java)을 보면

, 기능 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   } 

라인 1590에 관심을 켜기 및 염두에두고 이전과 동일한 파일에 우리가 가진 :

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

노드 ID가 간단한 해시 맵에 보관되어 있음을 알 수 있습니다. 클래스를 처리하는 방법을 찾는 것은 독자에게 남겨진 과제입니다.

다른 DOM 메소드 (예 : document.getElementByID(...))는 글자 코드와 과다한 객체 계층을 통해이 해시 맵에 연결됩니다 (참조).

+2

우수 답변 !! –