Sizzle: как работает движок селекторов в jQuery
Table of Contents
http://blog.bigbinary.com/2010/02/15/how-jquery-selects-elements-using-sizzle.html
Главное:
Если в браузере доступен document.querySelectorAll(), или достаточно методов document.getElementById() и document.getElementsByTagName(), то запрос к DOM-у будет передан этим методам, и потом ответ будет обёрнут в jQuery.
Интересное наступает, если этими методами обойтись нельзя.
Для примера возьмем старый браузер без document.querySelectorAll() и селектор
| 
					 1  | 
						$(".header a")  | 
					
Сначала строка разбивается по пробельным символам
| 
					 1  | 
						parts = ['.header', 'a']  | 
					
Затем справа налево начинаются вызовы к DOM (через jQuery.find())
Для этого сначала проводится проверка одиночного селектора по следующим регулярным выражениям
| 
					 1 2 3 4 5 6 7 8 9 10  | 
						match: {      ID: /#((?:[\w\u00c0-\uFFFF-]|\\.)+)/,      CLASS: /\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/,      NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/,      ATTR: /\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,      TAG: /^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/,      CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,      POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,      PSEUDO: /:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/ },  | 
					
Вот пример методов, соответствующим типам селекторов
| 
					 1 2 3  | 
						TAG: function(match, context){      return context.getElementsByTagName(match[1]); }  | 
					
В данном случае будут выбраны все теги a на странице. После этого для каждого будет проверен каждый его родитель на соответствие левому селектору (должен иметь класс header). Делается это методом dirCheck:
| 
					 1 2 3 4  | 
						dir = 'parentNode'; cur = ".header" checkSet = [ a www.neeraj.name, a www.google.com ] // object representation dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML )  | 
					
Основной смысл его выражен следующей строкой:
| 
					 1  | 
						if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n]/g, " ").indexOf(match) >= 0) ) // ^ - это XOR, исключающее "или"  | 
					
Из этого следует, что более специфичные селекторы нужно стараться размещать с самой правой стороны.
А ещё лучше для сложных селекторов делать несколько последовательных вызовов метода find().
Similar Posts
LEAVE A COMMENT
Для отправки комментария вам необходимо авторизоваться.