jQuery参考实例 1.5 对jQuery封装后的元素集进行过滤

本文翻译自jQuery Cookbook (O’Reilly 2009) 1.5 Filtering a Wrapper Set of DOM Elements

需求

对于一个jQuery封装后的元素集,需要从中移除不符合给定表达式的元素,从而创建一个新的元素集。

解决方案

jQuery提供一个叫做filter()的方法,在jQuery封装后的元素集上使用该方法,可以移除那些不符合给定表达式的元素。简而言之,filter()方法允许对现有元素集进行过滤。这一点和jQuery的find方法有很大不同,与filter相比,find方法通过选择器表达式在现有元素集中搜寻包括子元素在内的新元素。

看一下下面的代码,有助于理解filter方法:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"  
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>  
<head>  
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />  
</head>  
<body>  
  <a href="#" class="external">link</a>
  <a href="#" class="external">link</a>
  <a href="#"></a>
  <a href="#" class="external">link</a>
  <a href="#" class="external">link</a>
  <a href="#"></a></li>
  <a href="#">link</a>
  <a href="#">link</a>
  <a href="#">link</a>
  <a href="#">link</a>
  <script type="text/JavaScript"
    src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
  <script type="text/JavaScript">
    //alerts警告框显示,元素集经过过滤后仅剩4个元素
    alert(jQuery('a').filter('.external').length + ' external links');
</script>  
</body>  
</html>  

在上面的例子中,HTML网页包含了10个<a>元素,其中某些<a>元素的class被定义为external。首先我们使用jQuery函数选中了页面上所有的<a>元素,然后在该a元素集上使用filter方法,所有class属性值不为external的元素都将会从元素集中移除掉。在通过filter方法改变a元素集后,上述代码访问了新元素集的length属性,从而获取了新元素集的大小。

讨论

除了像上面的例子中给filter方法传一个表达式字符串,还可以通过向filter方法传一个函数来完成过滤工作。上述代码可以被改写为:

alert(  
  jQuery('a')
    .filter(function(index){ return $(this).hasClass('external');})
      .length + ' external links'
  );

在这个例子中,filter方法接受一个匿名函数。代码运行时,filter方法会对元素集进行循环,而匿名函数会以每一个循环到的元素作为上下文背景执行。也就是说,在匿名函数中使用$(this)的时候,$(this)指向的是元素集中循环到的那个DOM封装对象。在这个例子中,匿名函数会检查每一个<a>元素,看其class值是否包含”external”(hasClass())。如果包含,匿名函数返回true,该<a>元素被保留在元素集中;如果不包含,匿名函数返回false,该<a>元素则被移除。更准确的说,filter方法会检查匿名函数返回的值是否为false,只要匿名函数返回的是除了false以外的任何数据,当前循环到的元素就会被保留在元素集中。

值得注意的是,在以上匿名函数的例子中,匿名函数接受了一个未被使用的名为index的参数。该参数指代当前循环到的元素在元素集中的顺序值,需要时可用于对元素的过滤进行判定。