JQuery_2.1.0_日记 5.5 Sizzle选择器(三)

function Sizzle( selector, context, results, seed )
{

var match,
elem, m, nodeType,

// QSA vars

i, groups, old, nid, newContext, newSelector;

if (
( context ? context.ownerDocument || context : preferredDoc ) !== document ) {

setDocument( context );

}

//上下文为传入context或document

context = context || document;

//查询结果集

results = results || [];

//如果没传入选择器表达式或者传入的选择器表达器类型不是string

if (
!selector || typeof selector !== "string" )
{

//返回

return results;

}

//如果上下文不是Element或Document

//返回空结果集

if (
(nodeType = context.nodeType) !== 1 && nodeType !== 9 ) {

return [];

}

//文档是HTML并且没有传入候选集seed

if (
documentIsHTML && !seed ) {

// Shortcuts

// 快速匹配最常用的单一id tag class

//rquickExpr 捕获组1:id 捕获组2:tag 捕获组3:class

if (
(match = rquickExpr.exec( selector )) ) {

// Speed-up: Sizzle("#ID")

//id 分支

if (
(m = match[1]) ) {

//context是document

if (
nodeType === 9 ) {

elem = context.getElementById( m );

// Check parentNode to catch when
Blackberry 4.6 returns

// nodes that are no longer in the
document (jQuery #6963)

if (
elem && elem.parentNode ) {

// Handle the case where IE,
Opera, and Webkit return items

// by name instead of ID

//看上面注释!

if (
elem.id === m ) {

results.push( elem );

return results;

}

else {

return results;

}

else {

// Context is not a document

//得到上下文所属document,然后调用document.getElementById,并判断得到的elem是否属于contains并且看看elem的id属性是否等于m

if (
context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) &&

contains( context, elem ) && elem.id === m ) {

results.push( elem );

return results;

}

}

// Speed-up: Sizzle("TAG")

// tag分支

else if (
match[2] ) {

push.apply( results, context.getElementsByTagName( selector ) );

return results;

// Speed-up: Sizzle(".CLASS")

// class分支

else if (
(m = match[3]) && support.getElementsByClassName && context.getElementsByClassName ) {

push.apply( results, context.getElementsByClassName( m ) );

return results;

}

}

// QSA path

// 支持querySelectorAll,rbuggyQSA怪癖检查

if (
support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {

nid = old = expando;

newContext = context;

//newSelector的值为false或selector

//如果nodeType !== 9 返回false,其他返回selector

newSelector = nodeType === 9 && selector;

// qSA works strangely on Element-rooted queries

// We can work around this by specifying an extra
ID on the root

// and working up from there (Thanks to Andrew
Dupont for the technique)

// IE 8 doesn‘t work on object elements

//如果调通querySelectorAll的是Element会出现一些怪异的问题

//所以在媛selector的基础上方添加一个id的属性选择器

//例如媛selector:div a,修正后为[id=‘xx‘] div a

if (
nodeType === 1 && context.nodeName.toLowerCase() !== "object" )
{

groups = tokenize( selector );

//如果Element元素有id,则使用原来id

if (
(old = context.getAttribute("id" )) ) {

//rescape = /‘|\\/g

nid = old.replace( rescape, "\\$&" );

//没有id设置一个临时id,此id是expando属性

else {

context.setAttribute( "id",
nid );

}

nid = "[id=‘" +
nid + "‘] " ;

i = groups.length;

while (
i-- ) {

groups[i] = nid + toSelector( groups[i] );

}

newContext = rsibling.test( selector ) && testContext( context.parentNode ) || context;

newSelector = groups.join( ",");

}

//修正newSelector,调用querySelectorAll

if (
newSelector ) {

try {

push.apply( results,

newContext.querySelectorAll( newSelector )

);

return results;

catch(qsaError)
{

finally {

//如果用的时临时id

//删除

if (
!old ) {

context.removeAttribute( "id");

}

}

}

}

}

// All others

//原生方法不可用时,调用

return select(
selector.replace( rtrim, "$1" ), context, results, seed
);

}

JQuery_2.1.0_日记 5.5 Sizzle选择器(三)

时间: 2024-10-14 10:17:30

JQuery_2.1.0_日记 5.5 Sizzle选择器(三)的相关文章

JQuery_2.1.0_日记 5.4 Sizzle选择器(二)

(1) whitespace = "[\\x20\\t\\r\\n\\f]"; 匹配css3中空白符. \x20:空格;\t水平制表符(tab);\r\n回车换行\f换页符 (2) characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+" 匹配\后任意字符,字母或数字或-,ascii值非\00-\xa0范围内的字符 (3) identifier = characterEncoding.replace( "

JQuery_2.1.0_日记 5.4 Sizzle选择器(一) 正则中那些\\\\和\\

Sizzle中恐怖的正则. 字面量的正则也许还好理解,那么由字符串编译而成的正则呢. \\和\\\\ 由字符'\\\\'编译而成的正则是/\\/,第一个\转义第两个\,所以其匹配一个\字符(这个\字符是代表字符本身) Test_Script var s = '\\' ; alert(s); // '\' var rs = '\\\\' ; var matches = s.match(new RegExp(rs)); alert(matches[0]) // '\' 由字符串'\\3'编译而成的正

JQuery_2.1.0_日记 5.8 Sizzle选择器(四)

Sizzle( selector, context, results, seed )的关键步骤 1,传入的context对应的context和当前document是否一致,不一致调用setDocument()重新设置document,用于frame的情况. 2,如果context为空修正context为document 3,selector如果不是字符串或者context不是Element或Document直接返回空数组. 4,如果文档是HTML并且未传入过滤结果集seed,尝试用原生方法get

JQuery日记 5.11 Sizzle选择器(五)

//设置当前document和document对应的变量和方法 setDocument = Sizzle.setDocument = function( node ) { var hasCompare, //node为Element时返回node所属document //node为Document时返回node //node为空时返回window.document doc = node ? node.ownerDocument || node : preferredDoc, //document

JQuery日记_5.14 Sizzle选择器(七)

上篇说道,tokenize方法会把selector分割成一个个selector逻辑单元(如div>a是三个逻辑单元 'div','>','a')并为之片段赋予对应类型的过滤函数. for ( type in Expr.filter ) { if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] || (match = preFilters[ type ]( match ))) ) { matc

JQuery_2.1.0_日记 5.2

$.方法 (1)$.merge(first, second) 合并两个数组或类数组,将第二个数组添加到第一个数组的末尾 (2)$.grep(elems, callback, invert) 使用callback对elems进行过滤,如果invert设置为true.则返回保留callback返回值为false的元素数组,如果invert设置为false则返回callback返回值为true的元素数组. Test_Script var arr = ['a' , 'b' , 'c' ] arr = $

JQuery_2.1.0_日记 2014-5.1

JQuery工具方法. (1)$.isNumeric(obj) 此方法判断传入的对象是否是一个数字或者可以转换为数字. isNumeric: function( obj ) { // parseFloat NaNs numeric-cast false positives (null|true|false|"") // ...but misinterprets leading-number strings, particularly hex literals ("0x...&

JQuery日记_5.13 Sizzle选择器(六)选择器的效率

当选择表达式不符合快速匹配(id,tag,class)和原生QSA不可用或返回错误时,将调用select(selector, context, results, seed)方法,此方法迭代DOM选择.过滤元素, 在DOM树非常大的时候为了保证效率,应该保证html设计的合理,尽量使用可快速匹配(id,tag,class)的表达式,其次是QSA支持的选择器,尽量不要使用jquery扩展的selector和嵌套selector,然后是尽量不要使用位置伪类(它是从左向右查找,需要多次循环内套循环遍历)

JQuery_2.1.0_日记 4.29 $.extend

因为在JQuery一切皆JQuery,所以JQuery没有EXT那么恐怖的继承体系,比起EXT的Ext.extends(),$.extend()函数还是很好理解的,只是把一个对象的属性和方法添加到目标对象上.刚出生的JQuery是很弱小的,JQuery源码后面和我们自己扩展都是通过$.extend()函数. Test_Html <body> <div id= "div1">div1</div ><div id= "div2"