![]() |
![]() |
![]() |
![]() |
| HTML代码 | jQuery代码 | 结果 |
| <div>John Resig</div> <div>George Martin</div> <div>Malcom John Sinclair</div> <div>J. Ohn </div> |
$("div:contains('John')") | [ <div>John Resig</div>, <div>Malcom John Sinclair</div> ] |
首先我们先找到它的一个正则表达式
PSEUDO: /:((?:[\w\u00c0-\uFFFF_-]|\\.)+)(?:\((['"]*)((?:\([^\)]+\)|[^\2\(\)]*)+)\2\))?/
filter: { 
PSEUDO: function(elem, match, i, array)...{
var name = match[1], filter = Expr.filters[ name ];

if ( filter ) ...{
return filter( elem, i, match, array );
} else if ( name === "contains" ) ...{
// textContext在FF下和innerText在IE下的属性是等效的,match[3]得到的是contains紧跟在后面包含的字符串,当elem元素的文本内容包含contains包含的关键字时,返回true
return (elem.textContent || elem.innerText || "").indexOf(match[3]) >= 0;
} else if ( name === "not" ) ...{
var not = match[3];

for ( var i = 0, l = not.length; i < l; i++ ) ...{ 
if ( not[i] === elem ) ...{
return false;
}
}
return true;
}
}
}| HTML代码 | jQuery代码 | 结果 | |
| <table> <tr><td>Value 1</td><td></td></tr> <tr><td>Value 2</td><td></td></tr> </table> |
$("td:empty") | [ <td></td>, <td></td> ] | |
| <div><p>Hello</p></div> <div>Hello again!</div> |
$("div:has(p)").addClass("test"); | [ <div class="test"><p>Hello</p></div> ] | |
| <table> <tr><td>Value 1</td><td></td></tr> <tr><td>Value 2</td><td></td></tr> </table> |
$("td:parent") | [ <td>Value 1</td>, <td>Value 1</td> ] |
filters: { 
parent: function(elem)...{
return !!elem.firstChild;
}, 
empty: function(elem)...{
return !elem.firstChild;
}, 
has: function(elem, i, match)...{
return !!Sizzle( match[3], elem ).length;
}
}
jQuery.expr = Sizzle.selectors;
// … 
Sizzle.selectors.filters.hidden = function(elem)...{
return "hidden" === elem.type ||
jQuery.css(elem, "display") === "none" ||
jQuery.css(elem, "visibility") === "hidden";
};

Sizzle.selectors.filters.visible = function(elem)...{
return "hidden" !== elem.type &&
jQuery.css(elem, "display") !== "none" &&
jQuery.css(elem, "visibility") !== "hidden";
};
ATTR: /\[\s*((?:[\w\u00c0-\uFFFF_-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/
点击展开
filters: {
// 如 $("input[name^='news']")【<input name="newsletter" />】 
ATTR: function(elem, match)...{
var result = Expr.attrHandle[ match[1] ] ? Expr.attrHandle[ match[1] ]( elem ) : elem[ match[1] ] || elem.getAttribute( match[1] ), value = result + "", type = match[2], check = match[4];
return result == null ?
type === "!=" :
type === "=" ?
value === check :
type === "*=" ?
value.indexOf(check) >= 0 :
type === "~=" ?
(" " + value + " ").indexOf(check) >= 0 :
!match[4] ?
result :
type === "!=" ?
value != check :
type === "^=" ?
value.indexOf(check) === 0 :
type === "$=" ?
value.substr(value.length - check.length) === check :
type === "|=" ?
value === check || value.substr(0, check.length + 1) === check + "-" :
false;
}
}
CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/
点击展开
filter: { 
CHILD: function(elem, match)...{
var type = match[1], parent = elem.parentNode;
var doneName = match[0];

if ( parent && (!parent[ doneName ] || !elem.nodeIndex) ) ...{
var count = 1;

for ( var node = parent.firstChild; node; node = node.nextSibling ) ...{ 
if ( node.nodeType == 1 ) ...{
node.nodeIndex = count++;
}
}
parent[ doneName ] = count - 1;
}

if ( type == "first" ) ...{
return elem.nodeIndex == 1;
} else if ( type == "last" ) ...{
return elem.nodeIndex == parent[ doneName ];
} else if ( type == "only" ) ...{
return parent[ doneName ] == 1;
} else if ( type == "nth" ) ...{
var add = false, first = match[2], last = match[3];

if ( first == 1 && last == 0 ) ...{
return true;
}

if ( first == 0 ) ...{
// 形如 $("ul li:nth-child(2)") 
if ( elem.nodeIndex == last ) ...{
add = true;
}
}
// 形如 $("ul li:nth-child(even)"), $("ul li:nth-child(odd)"),$("ul li::nth-child(3n+1)") 
else if ( (elem.nodeIndex - last) % first == 0 && (elem.nodeIndex - last) / first >= 0 ) ...{
add = true;
}
return add;
}
}
}
PSEUDO: /:((?:[\w\u00c0-\uFFFF_-]|\\.)+)(?:\((['"]*)((?:\([^\)]+\)|[^\2\(\)]*)+)\2\))?/
点击展开
filters: { 
text: function(elem)...{
return "text" === elem.type;
}, 
radio: function(elem)...{
return "radio" === elem.type;
}, 
checkbox: function(elem)...{
return "checkbox" === elem.type;
}, 
file: function(elem)...{
return "file" === elem.type;
}, 
password: function(elem)...{
return "password" === elem.type;
}, 
submit: function(elem)...{
return "submit" === elem.type;
}, 
image: function(elem)...{
return "image" === elem.type;
}, 
reset: function(elem)...{
return "reset" === elem.type;
}, 
button: function(elem)...{
return "button" === elem.type || elem.nodeName.toUpperCase() === "BUTTON";
}, 
input: function(elem)...{
return /input|select|textarea|button/i.test(elem.nodeName);
}
}
PSEUDO: /:((?:[\w\u00c0-\uFFFF_-]|\\.)+)(?:\((['"]*)((?:\([^\)]+\)|[^\2\(\)]*)+)\2\))?/
filters: { 
enabled: function(elem)...{
return elem.disabled === false && elem.type !== "hidden";
}, 
disabled: function(elem)...{
return elem.disabled === true;
}, 
checked: function(elem)...{
return elem.checked === true;
}, 
selected: function(elem)...{
// Accessing this property makes selected-by-default
// options in Safari work properly
elem.parentNode.selectedIndex;
return elem.selected === true;
}
}