@ -1139,105 +1139,118 @@
// Tag( 标签)
// 如果支持getElementsByTagName, 则设置标签查找函数
Expr . find [ "TAG" ] = support . getElementsByTagName ?
function ( tag , context ) {
if ( typeof context . getElementsByTagName !== "undefined" ) {
return context . getElementsByTagName ( tag ) ;
// DocumentFragment节点没有gEBTN
} else if ( support . qsa ) {
return context . querySelectorAll ( tag ) ;
// 设置`Expr.find["TAG"]`函数,它用于根据标签名查找元素,其具体的实现逻辑会根据浏览器对相关方法的支持情况有所不同。
// 如果浏览器支持`getElementsByTagName`方法(通过`support.getElementsByTagName`判断,这个变量应该是在前面代码中已经确定好是否支持该方法,并存储了相应的布尔值结果),则采用以下函数作为`Expr.find["TAG"]`的实现。
Expr . find [ "TAG" ] = support . getElementsByTagName ?
function ( tag , context ) {
// 首先判断传入的查找上下文`context`是否具有`getElementsByTagName`方法(确保可以在该上下文中通过标签名来查找元素),如果有该方法,则直接调用`context.getElementsByTagName(tag)`来查找具有指定标签名`tag`的所有元素,并返回查找结果。
// 这里注释提到了`DocumentFragment`节点没有`gEBTN`(推测这里`gEBTN`是`getElementsByTagName`的缩写,意思是提醒`DocumentFragment`这种节点类型在使用这个方法时可能存在特殊情况,不过此处代码逻辑上只是简单调用该方法进行查找,具体的特殊处理可能在更外层或者其他相关地方体现)。
if ( typeof context . getElementsByTagName !== "undefined" ) {
return context . getElementsByTagName ( tag ) ;
// DocumentFragment节点没有gEBTN
} else if ( support . qsa ) {
// 如果`context`没有`getElementsByTagName`方法,但浏览器支持`qsa`(即`querySelectorAll`方法,同样`support.qsa`应该是前面已经判断好是否支持该方法的布尔值变量),则通过`context.querySelectorAll(tag)`方法来查找具有指定标签名`tag`的所有元素,并返回查找结果,这是一种备用的查找元素的方式,用于在不支持`getElementsByTagName`时尝试使用`querySelectorAll`来满足查找需求。
return context . querySelectorAll ( tag ) ;
}
} :
// 如果浏览器不支持`getElementsByTagName`方法,则采用以下函数作为`Expr.find["TAG"]`的实现,这是另一种处理标签查找的逻辑(可能用于兼容性处理或者在特定环境下的查找方式)。
// 以下代码看起来像是在处理一种不太理想的查找情况,可能针对一些特殊的`DocumentFragment`等场景或者浏览器不支持常规查找方法时的备用逻辑,不过此处代码似乎被截断了(注释中也提到通常应包含遍历`results`并处理每个元素的逻辑,说明完整的逻辑应该还有后续对查找到的元素进行进一步处理的部分)。
function ( tag , context ) {
var elem ,
tmp = [ ] ,
i = 0 ,
// 幸运的是,一个损坏的`gEBTN`也出现在`DocumentFragment`节点上(这里再次强调了在`DocumentFragment`节点上使用`getElementsByTagName`方法可能存在问题,不过从代码看还是尝试调用了该方法进行查找,后续应该还有针对查找结果处理的逻辑来应对可能出现的异常情况等),通过`context.getElementsByTagName(tag)`获取具有指定标签名`tag`的元素集合,并将结果存储在`results`变量中,后续应该会对这个`results`集合进行遍历等操作来进一步筛选或者处理元素,但代码未完整展示这部分内容。
results = context . getElementsByTagName ( tag ) ;
// 此处代码被截断, 通常应包含遍历results并处理每个元素的逻辑
} ;
// 如果查找的标签名`tag`是`"*"`( 代表查找所有元素的情况) , 则进入以下循环处理逻辑, 目的是对查找到的元素进行筛选, 只保留节点类型为元素节点( 在DOM中, 节点类型为1表示元素节点) 的元素, 将其添加到`tmp`数组中,最后返回`tmp`数组作为最终的查找结果。
if ( tag === "*" ) {
while ( ( elem = results [ i ++ ] ) ) {
if ( elem . nodeType === 1 ) {
tmp . push ( elem ) ;
}
}
return tmp ;
}
} :
// 如果不支持getElementsByTagName, 则设置标签查找函数
function ( tag , context ) {
var elem ,
tmp = [ ] ,
i = 0 ,
// 幸运的是, 一个损坏的gEBTN也出现在DocumentFragment节点上
results = context . getElementsByTagName ( tag ) ;
// 此处代码被截断, 通常应包含遍历results并处理每个元素的逻辑
// 如果查找的标签名`tag`不是`"*"`,则直接返回之前查找到的`results`(不管是通过`getElementsByTagName`还是其他备用方式查找到的元素集合)作为最终的查找结果,这里没有进行额外的筛选等操作,直接返回原始的查找结果集合。
return results ;
} ;
if ( tag === "*" ) {
while ( ( elem = results [ i ++ ] ) ) {
if ( elem . nodeType === 1 ) {
tmp . push ( elem ) ;
// Class
// 设置`Expr.find["CLASS"]`函数,用于根据类名查找元素,同样其实现依赖于浏览器对相关方法的支持情况以及文档类型等因素。
// 如果浏览器支持`getElementsByClassName`方法(通过`support.getElementsByClassName`判断) , 并且当前文档是HTML文档( 通过`documentIsHTML`判断, 前面代码中应该有对该变量的赋值, 用于确定文档类型是否为HTML) , 则以下函数作为`Expr.find["CLASS"]`的实现,它会调用`context.getElementsByClassName(className)`方法在给定的上下文`context`中查找具有指定类名`className`的所有元素,并返回查找结果。
Expr . find [ "CLASS" ] = support . getElementsByClassName && function ( className , context ) {
if ( typeof context . getElementsByClassName !== "undefined" && documentIsHTML ) {
return context . getElementsByClassName ( className ) ;
}
}
return tmp ;
}
return results ;
} ;
// Class
Expr . find [ "CLASS" ] = support . getElementsByClassName && function ( className , context ) {
if ( typeof context . getElementsByClassName !== "undefined" && documentIsHTML ) {
return context . getElementsByClassName ( className ) ;
}
} ;
/ * Q S A / m a t c h e s S e l e c t o r
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- * /
// QSA and matchesSelector support
// matchesSelector(:active) reports false when true (IE9/Opera 11.5)
rbuggyMatches = [ ] ;
// qSa(:focus) reports false when true (Chrome 21)
// We allow this because of a bug in IE8/9 that throws an error
// whenever `document.activeElement` is accessed on an iframe
// So, we allow :focus to pass through QSA all the time to avoid the IE error
// See http://bugs.jquery.com/ticket/13378
rbuggyQSA = [ ] ;
} ;
if ( ( support . qsa = rnative . test ( document . querySelectorAll ) ) ) {
// Build QSA regex
// Regex strategy adopted from Diego Perini
assert ( function ( div ) {
// Select is set to empty string on purpose
// This is to test IE's treatment of not explicitly
// setting a boolean content attribute,
// since its presence should be enough
// http://bugs.jquery.com/ticket/12359
docElem . appendChild ( div ) . innerHTML = "<a id='" + expando + "'></a>" +
"<select id='" + expando + "-\r\\' msallowcapture=''>" +
"<option selected=''></option></select>" ;
// Support: IE8, Opera 11-12.16
// Nothing should be selected when empty strings follow ^= or $= or *=
// The test attribute must be unknown in Opera but "safe" for WinRT
// http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
if ( div . querySelectorAll ( "[msallowcapture^='']" ) . length ) {
rbuggyQSA . push ( "[*^$]=" + whitespace + "*(?:''|\"\")" ) ;
}
/ * Q S A / m a t c h e s S e l e c t o r
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- * /
// QSA and matchesSelector support
// `rbuggyMatches`数组用于记录一些存在问题的`matchesSelector`匹配情况, 比如在某些浏览器中( 如IE9/Opera 11.5) , `matchesSelector(:active)`在应该返回`true`时却报告为`false`,这些有问题的选择器相关的情况会被记录到这个数组中,方便后续进行针对性的处理或者判断(不过目前代码中还未展示具体如何使用这个数组来处理问题,只是进行了定义和相关情况的记录)。
// matchesSelector(:active) reports false when true (IE9/Opera 11.5)
rbuggyMatches = [ ] ;
// `rbuggyQSA`数组用于记录一些存在问题的`querySelectorAll`(简称`qsa`)使用情况,例如在某些浏览器版本中,`qSa(:focus)`在应该返回`true`时却报告为`false`( 如Chrome 21) , 但由于IE8/9存在一个错误, 每当访问`document.activeElement`在`iframe`中时会抛出异常,所以这里允许`:focus`始终通过`QSA`来避免IE的错误( 相关的详细原因和背景信息可以查看对应的链接`http://bugs.jquery.com/ticket/13378`),像这样有问题的`qsa`相关的选择器情况会被记录到这个数组中,后续可用于对`querySelectorAll`的使用进行限制或者特殊处理等操作。
// qSa(:focus) reports false when true (Chrome 21)
// We allow this because of a bug in IE8/9 that throws an error
// whenever `document.activeElement` is accessed on an iframe
// So, we allow :focus to pass through QSA all the time to avoid the IE error
// See http://bugs.jquery.com/ticket/13378
rbuggyQSA = [ ] ;
// 判断浏览器是否支持`querySelectorAll`方法,通过`rnative.test(document.querySelectorAll)`来检测(`rnative`应该是一个用于进行某种检测的对象或者正则表达式等,通过其`test`方法来判断`document.querySelectorAll`是否符合某种原生支持的条件,以此确定浏览器是否支持`querySelectorAll`方法),如果支持,则将`support.qsa`设置为`true`(用于记录浏览器对该方法的支持情况,方便后续代码根据这个支持状态进行不同的逻辑处理),并且进入以下逻辑块进行一些和`querySelectorAll`相关的问题检测及记录等操作。
if ( ( support . qsa = rnative . test ( document . querySelectorAll ) ) ) {
// Build QSA regex
// Regex strategy adopted from Diego Perini( 这里注释说明构建`QSA`正则表达式的策略是采用自Diego Perini的方法, 可能是参考了别人的思路或者代码来进行相关的正则表达式构建等操作)
assert ( function ( div ) {
// Select is set to empty string on purpose( 这里特意将`select`属性设置为空字符串,可能是为了测试某些浏览器对于没有明确设置布尔型内容属性的处理情况,从注释看是为了验证相关的一种属性处理逻辑,具体的验证背景和目的可以参考链接`http://bugs.jquery.com/ticket/12359`)
// This is to test IE's treatment of not explicitly
// setting a boolean content attribute,
// since its presence should be enough
// http://bugs.jquery.com/ticket/12359
docElem . appendChild ( div ) . innerHTML = "<a id='" + expando + "'></a>" +
"<select id='" + expando + "-\r\\' msallowcapture=''>" +
"<option selected=''></option></select>" ;
// Support: IE8, Opera 11-12.16( 说明以下代码针对IE8以及Opera 11 - 12.16版本浏览器的支持情况以及相关的测试逻辑)
// Nothing should be selected when empty strings follow ^= or $= or *=(当空字符串跟随`^=`、`$=`或者`*=`时,不应该有元素被选中,这里是在测试`querySelectorAll`在这种特定选择器格式下的表现是否符合预期,通过判断是否有元素被选中来确定是否存在问题)
// The test attribute must be unknown in Opera but "safe" for WinRT( 在Opera中测试属性必须是未知的, 但对于WinRT是“安全的”, 这里涉及到不同平台和浏览器对于特定属性在`querySelectorAll`操作中的一些兼容性和安全性相关的要求及特点)
// http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
if ( div . querySelectorAll ( "[msallowcapture^='']" ) . length ) {
rbuggyQSA . push ( "[*^$]=" + whitespace + "*(?:''|\"\")" ) ;
}
// Support: IE8
// Boolean attributes and "value" are not treated correctly
if ( ! div . querySelectorAll ( "[selected]" ) . length ) {
rbuggyQSA . push ( "\\[" + whitespace + "*(?:value|" + booleans + ")" ) ;
}
// Support: IE8 ( 说明以下代码针对IE8浏览器的支持情况以及相关的测试逻辑)
// Boolean attributes and "value" are not treated correctly ( 布尔型属性和“value”属性在某些情况下没有被正确处理, 这里是在测试`querySelectorAll`对于这些属性相关的选择器的处理是否准确,通过判断是否能正确选中相应元素来发现可能存在的问题)
if ( ! div . querySelectorAll ( "[selected]" ) . length ) {
rbuggyQSA . push ( "\\[" + whitespace + "*(?:value|" + booleans + ")" ) ;
}
// Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+
if ( ! div . querySelectorAll ( "[id~=" + expando + "-]" ) . length ) {
rbuggyQSA . push ( "~=" ) ;
}
// Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+ (说明以下代码针对这些浏览器版本及平台的支持情况以及相关的测试逻辑)
if ( ! div . querySelectorAll ( "[id~=" + expando + "-]" ) . length ) {
rbuggyQSA . push ( "~=" ) ;
}
// Webkit/Opera - :checked should return selected option elements
// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
// IE8 throws error here and will not see later tests
if ( ! div . querySelectorAll ( ":checked" ) . length ) {
rbuggyQSA . push ( ":checked" ) ;
}
// Webkit/Opera - :checked should return selected option elements ( 在Webkit/Opera浏览器中, `:checked`选择器应该返回被选中的选项元素,这里是在测试`querySelectorAll`对于`:checked`选择器的处理是否符合这个要求,通过判断是否能正确返回相应元素来发现可能存在的问题)
// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
// IE8 throws error here and will not see later tests ( IE8在这个测试中会抛出错误, 并且不会执行后续的测试, 这里提醒了IE8在这种测试场景下的特殊情况, 后续代码需要考虑到这种情况可能导致的影响)
if ( ! div . querySelectorAll ( ":checked" ) . length ) {
rbuggyQSA . push ( ":checked" ) ;
}
// Support: Safari 8+, iOS 8+
// https://bugs.webkit.org/show_bug.cgi?id=136851
// In-page `selector#id sibing-combinator selector` fails
if ( ! div . querySelectorAll ( "a#" + expando + "+*" ) . length ) {
rbuggyQSA . push ( ".#.+[+~]" ) ;
}
} ) ;
// Support: Safari 8+, iOS 8+ (说明以下代码针对这些浏览器版本及平台的支持情况以及相关的测试逻辑)
// https://bugs.webkit.org/show_bug.cgi?id=136851 (这里给出了相关问题的链接,可能可以通过链接查看更详细的关于这个问题的描述及背景信息)
// In-page `selector#id sibing-combinator selector` fails (页面内的`selector#id sibing-combinator selector`这种选择器组合会失败,这里是在测试`querySelectorAll`对于这种复杂选择器组合的处理是否正确,通过判断是否能正确选中相应元素来发现可能存在的问题)
if ( ! div . querySelectorAll ( "a#" + expando + "+*" ) . length ) {
rbuggyQSA . push ( ".#.+[+~]" ) ;
}
} ) ;
assert ( function ( div ) {
// Support: Windows 8 Native Apps