没有必要提供与过滤器结合使用的实际元素,例如 $('div:hidden')
。在需要选择器表达式的任何地方都可以简单地单独传递过滤器。
一些例子:
// Selects all hidden elements $(':hidden'); // Selects all div elements, then selects only even elements $('div').filter(':even');
自定义 jQuery 选择器过滤器 :hidden
和 :visible
没有像人们预期的那样考虑 CSS 可见性属性。 jQuery 确定元素是否隐藏或可见的方式是该元素是否占用文档中的任何空间。确切地说,如果浏览器报告的 offsetWidth
或 offsetHeight
大于 0,则该元素是可见的。这样,一个元素可能具有 display
的 CSS 值 block
包含在具有 display
none
会准确报告它不可见。
仔细检查代码并确保您理解为什么返回的值是 true
,即使选择的 具有
display:block
的内联样式。
<!DOCTYPE html> <html lang="en"> <body> <div id="parentDiv" style="display: none;"> <div id="childDiv" style="display: block;"></div> </div> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script> <script> (function($){ // Returns true because the parent div is hidden, so the // encapsulated div reports zero offsetWidth and offsetHeight alert($('#childDiv').is(':hidden')); })(jQuery); </script> </body> </html>
通常需要确定所选元素集是否确实包含特定元素。使用 is()
方法,我们可以根据表达式/过滤器检查当前集。如果该集合至少包含一个由给定表达式/过滤器选择的元素,则检查将返回 true
。如果不包含该元素,则返回 false
值。检查以下代码:
<!DOCTYPE html> <html lang="en"> <body> <div id="i0">jQuery</div> <div id="i1">jQuery</div> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script> <script> (function($){ // Returns true alert($('div').is('#i1')); // Returns false. Wrapper set contains no <div> with id="i2" alert($('div').is('#i2')); // Returns false. Wrapper set contains no hidden <div> alert($('div').is(':hidden')); })(jQuery); </script> </body> </html>
很明显,第二个 alert()
将返回 false 值,因为我们的包装器集不包含具有 id
属性值 i2
的 。
is()
方法对于确定包装器集是否包含特定元素非常方便。
注释:从 jQuery 1.3 开始,is()
方法支持所有表达式。以前,诸如包含层次结构选择器的复杂表达式(例如 +
、~
和 >
)始终返回 true
。
过滤器由其他内部 jQuery 函数使用。因此,适用于此处的所有规则也适用于此处。
一些开发人员使用 is('.class')
来确定元素是否具有特定的类。不要忘记 jQuery 已经有一种方法可以执行此操作,称为 hasClass('class')
,该方法可用于包含多个类值的元素。但说实话, hasClass()
只是 is()
方法的一个方便的包装。
您可以为 jQuery 函数的第一个参数提供多个用逗号分隔的表达式:$('表达式, 表达式, 表达式')
。换句话说,您不限于仅使用单个表达式来选择元素。例如,在下面的示例中,我向 jQuery 函数传递了三个用逗号分隔的表达式。
<!DOCTYPE html> <html lang="en"> <body> <div>jQuery </div> <p>is the </p> <ul> <li>best!</li> </ul> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script> <script> (function ($) { // Alerts jQuery is the best! alert($('div, p, ul li').text()); // Inefficient way. Alerts jQuery is the best! alert($('div').text() + $('p').text() + $('ul li').text()); })(jQuery); </script> </body> </html>
每个表达式都会选择全部添加到包装器集中的 DOM 元素。然后我们可以使用 jQuery 方法对这些元素进行操作。请记住,所有选定的元素都将放置在同一个包装集中。执行此操作的低效方法是调用 jQuery 函数三次,每个表达式调用一次。
可以通过检查包装器集是否有长度来确定表达式是否选择了任何内容。您可以使用数组属性 length
来执行此操作。如果 length
属性不返回 0,那么您就知道至少有一个元素与您传递给 jQuery 函数的表达式相匹配。例如,在下面的代码中,我们检查页面中是否存在 id
为“notHere”的元素。你猜怎么了?它不在那里!
<!DOCTYPE html> <html lang="en"> <body> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script> <script> (function($){ // Alerts "0" alert($('#notHere').length); })(jQuery); </script> </body> </html>
注释: 如果不明显,length 属性还可以报告包装器集中的元素数量 - 换句话说,传递给 jQuery 函数的表达式选择了多少元素.
可以通过创建您自己的自定义过滤器来扩展 jQuery 选择器引擎的功能。理论上,您在这里所做的一切都是基于已经是 jQuery 一部分的自定义选择器。例如,假设我们想要选择网页上绝对定位的所有元素。由于 jQuery 还没有自定义 :positionAbsolute
过滤器,因此我们可以创建自己的过滤器。
<!DOCTYPE html> <html lang="en"> <body> <div style="position: absolute">absolute</div> <span style="position: absolute">absolute</span> <div>static</div> <div style="position: absolute">absolute</div> <div>static</div> <span style="position: absolute">absolute</span> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script> <script> (function ($) { // Define custom filter by extending $.expr[':'] $.expr[':'].positionAbsolute = function (element) { return $(element).css('position') === 'absolute'; }; // How many elements in the page are absolutely positioned? alert($(':positionAbsolute').length); // Alerts "4" // How many div elements are absolutely positioned? alert($('div:positionAbsolute').length); // Alerts "2" })(jQuery); </script> </body> </html>
这里要掌握的最重要的一点是,您不限于 jQuery 提供的默认选择器。您可以创建自己的。然而,在您花时间创建自己的选择器版本之前,您可以简单地尝试具有指定过滤函数的 filter()
方法。例如,我可以通过简单地使用传递给 filter()
方法的函数来过滤前面示例中的 元素,从而避免编写
:positionAbsolute
选择器。
// Remove <div> elements from the wrapper // set that are not absolutely positioned $('div').filter(function () { return $(this).css('position') === 'absolute'; }); // or // Remove all elements from the wrapper // set that are not absolutely positioned $('*').filter(function () { return $(this).css('position') === 'absolute'; });
注释:有关创建自己的选择器的更多信息,我建议阅读以下内容:http://www.bennadel.com/blog/1457-How-To-Build-A-Custom- jQuery-Selector.htm
jQuery 提供了过滤器,用于通过集合中元素的数字上下文来过滤包装器集。
这些过滤器是:
:first
:last
:even
:odd
:eq(index)
:gt(index)
:lt(index)
注释:过滤包装器集本身的过滤器通过过滤集合中起始点 0 或索引 0 的元素来实现这一点。例如 :eq(0)
和:first
访问集合中的第一个元素 - $('div:eq(0)')
- 索引为 0。这与单索引的 :nth-child
过滤器形成对比。这意味着,例如 :nth-child(1)
将返回第一个子元素,但尝试使用 :nth-child(0)
将不起作用。使用 :nth-child(0)
将始终不选择任何内容。
使用 :first
将选择集合中的第一个元素,而 :last
将选择集合中的最后一个元素。请记住,它们根据集合内的关系(从 0 开始的数字层次结构)过滤集合,而不是 DOM 上下文中元素的关系。有了这些知识,就应该很明显为什么过滤器 :first
、:last
和 :eq(index)
将始终返回单个元素。
如果还不是很明显,请允许我进一步解释。 :first
只能返回单个元素的原因是,当只有一个集合时,集合中只能有一个元素被首先考虑。这应该是相当合乎逻辑的。检查下面的代码,看看这个概念的实际应用。
<!DOCTYPE html> <html lang="en"> <body> <ul> <li>1</li> <li>2</li> <li>3</li> <li>4</li> <li>5</li> </ul> <ul> <li>6</li> <li>7</li> <li>8</li> <li>9</li> <li>10</li> </ul> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script> <script> (function ($) { // Remember that text() combines the contents of all // elements in the wrapper set into a single string. alert('there are ' + $('li').length + ' elements in the set'); // Get me the first element in the set alert($('li:first').text()); // Alerts "1" // Get me the last element in the set alert($('li:last').text()); // Alerts "10" // Get me the 6th element in the set, 0 based index alert($('li:eq(5)').text()); // Alerts "6" })(jQuery); </script> </body> </html>
有了对操作集合本身的清晰理解,我们可以通过使用过滤器来选择与实际 DOM 中其他元素具有唯一关系的元素,从而增强对选择元素的理解。 jQuery 提供了几个选择器来执行此操作。其中一些选择器是自定义的,而另一些则是众所周知的用于选择 DOM 元素的 CSS 表达式。
祖先后代
父级>子
上一个 + 下一个
prev ~ 兄弟姐妹
:nth-child(选择器)
:first-child
:last-child
:only-child
:empty
:has(选择器)
:parent
使用这些选择器过滤器将根据元素在 DOM 中与 DOM 中其他元素的关系来选择元素。为了演示这个概念,让我们看一些代码。
<!DOCTYPE html> <html lang="en"> <body> <ul> <li>1</li> <li>2</li> <li>3</li> <li>4</li> <li>5</li> </ul> <ul> <li>1</li> <li>2</li> <li>3</li> <li>4</li> <li>5</li> </ul> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script> <script> (function ($) { // Remember that text() combines the contents of all // elements in the wrapper set into a single string. alert($('li:nth-child(2)').text()); // Alerts "22" alert($('li:nth-child(odd)').text()); // Alerts "135135" alert($('li:nth-child(even)').text()); // Alerts "2424" alert($('li:nth-child(2n)').text()); // Alerts "2424" })(jQuery); </script> </body> </html>
如果您对 $('li:nth-child(odd)').text()
返回值 135135 感到惊讶,那么您还没有掌握关系过滤器。 $('li:nth-child(odd)')
口头上说的是“查找网页中所有属于子元素的 元素,然后按奇数子元素过滤它们”。好吧,碰巧页面中有两个结构,它们有一组由
s 组成的兄弟结构。我的观点是这样的:包装器集由基于过滤器的元素组成,该过滤器考虑了元素与 DOM 中其他元素的关系。这些关系可以在多个位置找到。
要记住的概念是,并非所有过滤器都是平等创建的。确保您了解哪些是基于 DOM 关系进行过滤的,例如:only-child
-以及哪些按元素的位置进行过滤-例如:eq()
-在包装集中。
jQuery 选择器使用一组元字符(例如 # ~ [] = >
),当用作名称的文字部分时(例如 id="#foo[bar]"
)应该被逃脱。可以通过在字符前放置两个反斜杠来转义字符。检查下面的代码,了解如何在选择表达式中使用两个反斜杠来选择 id 属性值为 #foo[bar]
的元素。
<!DOCTYPE html> <html lang="en"> <body> <div id="#foo[bar]">jQuery</div> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script> <script> (function ($) { // Alerts "jQuery" alert($('#\#foo\[bar\]').text()); })(jQuery); </script> </body> </html>
以下是用作名称的文字部分时需要转义的字符的完整列表。
#
;
&
,
.
+
*
~
'
:
“
!
^
$
[
]
(
)
=
>
|
/
可以堆叠选择器过滤器 - 例如a[title="jQuery"][href^="http://"]
.一个明显的例子是选择一个具有特定属性和特定属性值的元素。例如,下面的 jQuery 代码将仅选择 HTML 页面中的 元素:
href
属性,起始值为“http://”title
属性<!DOCTYPE html> <html lang="en"> <body> <a title="jQuery">jQuery.com</a> <a href="http://www.jquery.com" title="jQuery" class="foo">jQuery.com 1</a> <a href="">jQuery.com</a> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script> <script> (function ($) { // Alerts "1" alert($('a[title="jQuery"][href^="http://"]').length); })(jQuery); </script> </body> </html>
请注意代码中我们如何堆叠两个过滤器来完成此选择。
除了属性过滤器之外,还可以堆叠其他选择器过滤器。例如:
// Select the last <div> contained in the // wrapper set that contains the text "jQuery" $('div:last:contains("jQuery")') // Get all check boxes that are both visible and selected $(':checkbox:visible:checked')
要掌握的概念是选择器过滤器可以堆叠并组合使用。
注释:您还可以嵌套和堆叠过滤器 - 例如$('p').filter(':not(:first):not(:last)')
选择器过滤器可以嵌套。这使您能够以非常简洁和强大的方式使用过滤器。下面,我将举例说明如何嵌套过滤器来执行复杂的过滤。
<!DOCTYPE html> <html lang="en"> <body> <div>javascript</div> <div><span class="jQuery">jQuery</span></div> <div>javascript</div> <div><span class="jQuery">jQuery</span></div> <div>javascript</div> <div><span class="jQuery">jQuery</span></div> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script> <script> (function ($) { // Select all div's, remove all div's that have a child element with class="jQuery" alert($('div:not(:has(.jQuery))').text()); // Alerts combined text of all div's // Select all div's, remove all div's that are odd in the set (count starts at 0) alert($('div:not(:odd)').text()); // Alerts combined text of all div's })(jQuery); </script> </body> </html>
要掌握的概念是选择器过滤器可以嵌套。
注释:您还可以嵌套和堆叠过滤器 - 例如$('p').filter(':not(:first):not(:last)')
:nth-child()
过滤器有很多用途。例如,假设您只想选择
元素中包含的每三个 元素。可以使用
:nth-child()
过滤器。检查以下代码以更好地了解如何使用 :nth-child()
过滤器。
<!DOCTYPE html> <html lang="en"> <body> <ul> <li>1</li> <li>2</li> <li>3</li> <li>4</li> <li>5</li> <li>6</li> <li>7</li> <li>8</li> <li>9</li> <li>10</li> </ul> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script> <script> (function ($) { // Remember that text() combines the contents of all // elements in the wrapper set into a single string. // By index alert($('li:nth-child(1)').text()); // Alerts "1" // By even alert($('li:nth-child(even)').text()); // Alerts "246810" // By odd alert($('li:nth-child(odd)').text()); // Alerts "13579" // By equation alert($('li:nth-child(3n)').text()); // Alerts "369" // Remember this filter uses a 1 index alert($('li:nth-child(0)').text()); // Alerts nothing. There is no 0 index. })(jQuery); </script> </body> </html>
当用于选择元素的 jQuery 属性过滤器不够健壮时,请尝试使用正则表达式。 James Padolsey 为过滤器选择器编写了一个很好的扩展,它允许我们创建用于过滤的自定义正则表达式。我在这里提供了一个代码示例,但请确保您还查看了 http://james.padolsey.com 上的文章以了解所有详细信息。
<!DOCTYPE html> <html lang="en"> <body> <div id="123"></div> <div id="oneTwoThree"></div> <div id="0"></div> <div id="zero"><div> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script> <script> (function ($) { //James Padolsey filter extension jQuery.expr[':'].regex = function (elem, index, match) { var matchParams = match[3].split(','), validLabels = /^(data|css):/, attr = { method: matchParams[0].match(validLabels) ? matchParams[0].split(':')[0] : 'attr', property: matchParams.shift().replace(validLabels, '') }, regexFlags = 'ig', regex = new RegExp(matchParams.join('').replace(/^s+|s+$/g, ''), regexFlags); return regex.test(jQuery(elem)[attr.method](attr.property)); } // Select div's where the id attribute contains numbers alert($('div:regex(id,[0-9])').length); // Alerts "2" // Select div's where the id attribute contains the string "Two" alert($('div:regex(id, Two)').length); // Alerts "1" })(jQuery); </script> </div></div></body> </html>
直接子元素只能通过使用组合器 >
或通过 children()
遍历方法来选择。可以使用 *
CSS 表达式选择所有后代。确保您清楚地了解两者之间的区别。下面的示例演示了这些差异。
<!DOCTYPE html> <html lang="en"> <body> <div> <p><strong><span>text</span></strong></p> <p><strong><span>text</span></strong></p> </div> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script> <script> (function ($) { // Each statement alerts "2" because there are // two direct child <p> elements inside of <div> alert($('div').children().length); // or alert($('>*', 'div').length); alert($('div').find('>*').length); // Each statement alerts 6 because the <div> contains // 6 descendants, not including the text node. alert($('div').find('*').length); // or alert($('*', 'div').length); })(jQuery); </script> </body> </html>
当已经提供了上下文时,可以在没有上下文的情况下使用组合器 >
来选择直接子元素。检查下面的代码。
<!DOCTYPE html> <html lang="en"> <body> <ul id="firstUL"> <li>text</li> <li> <ul id="secondUL"> <li>text</li> <li>text</li> </ul> </li> <li>text</li> </ul> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script> <script> (function ($) { // Select only the direct <li> children. Alerts "3". alert($('ul:first').find('> li').length); // or alert($('> li', 'ul:first').length); } )(jQuery); </script> </body> </html>
基本上,当上下文已经确定时,'>元素'
可以用作表达式。