jQuery选择器和选取方法(二)

上一篇文章jQuery选择器和选取方法(一)讲解了 JQuery 选择器.今天将说下选择的选取方法.

选取方法

除了$()函数支持的选择器语法,jQuery还定义了一些选取方法。本章中我们已看到过的大部分jQuery方法都是在选中元素上执行某种操作。选取方法不一样:它们会修改选中元素集,对其进行提取、扩充或仅作为新选取操作的起点。

本节描述这些选取方法。你会注意到这些选取方法中的多数提供的功能与选择器语法的功能是一样的。

提取选中元素最简单的方式是按位置提取。first()返回的jQuery对象仅包含选中元素中的第一个,last()返回的jQuery对象则只 包含最后一个元素。更通用的是,eq()方法返回物Query对象只包含指定序号的单个选中元素。(在jQuery 1.4中,负序号也是允许的,会从选区的末尾开始计数。)注意这些方法返回的jQuery对象只含有一个元素。这与常见的数组序号是不一样的,数组序号返 回的单一元素没有经过jQuery包装:

1
2
3
4
5
6
var paras=$("p");
paras.first() //仅选取第一个<p>元素
paras.last() //仅选取最后一个<P>
paras.eq(1) //选取第二个<P>
paras.eq(-2) //选取倒数第二个<P>
paras[1] //第二个<P>元素自身

通过位置提取选区更通用的方法是slice()o jQuery的slice()方法与Array.slice()方法类似:前者接受开始和结束序号(负序号会从结尾处计算),返回的jQuery对象包含 从开始到结束序号(但不包含结束序号)处的元素集。如果省略结束序号,返回的对象会包含从开始序号起的所有元素:

1
2
$("p").slice(2,5)       //选取第3个、第4个和第5个<P>元素
$("div").slice(-3) //选取最后3个<div>元素

filter()是通用的选区过滤方法,有3种调用方式:

  • 传递选择器字符串给filter(),它会返回一}jQuery对象,仅包含也匹配该选择器的选中元素。
  • 传递另一个jQuery对象给filter(),它会返回一个新的jQuery对象,该对象包含这两们Query对象的交集。也可以传递元素数组甚至单一文档元素给filter()
  • 传递判断函数给filter(),会为每一个匹配元素调用该函数,filter()则返回一个jQuery对象,仅包含判断函数为true(或任意真值)的元素。在调用判断函数时,this值为当前元素,参数是元素序号。
1
2
3
$("div").filter(".note")        //与$("div.note")一样
$("div").filter($(".note")) //与$("div.note")一样
$("div").filter(function(idx){return idx%2 == 0}) //与$("div:even")一样

not()方法与filter()一样,除了含义与filter()相反。如果传递选择器字符串给not()它会返回一个新的jQuery对象,该 对象只包含不匹配该选择器的元素。如果传递jQuery对象、元素数组或单一元素给not(),它会返回除了显式排除的元素之外的所有选中元素。如果传递 判断函数给not(),该判断函数的调用就与在filter()中一样,只是返回的jQuery对象仅包含那些使得判断函数返回false或其他假值的元 素:

1
$("div").not("#header, #footer");        //除了两个特殊元素之外的所有元素

在jQuery 1.4中,提取选区的另一种方式是has()方法。如果传入选择器,has()会返回一个新的jQuery对象,仅包含有子孙元素匹配该选择器的选中元素。如果传入文档元素给has(),它会将选中元素集调整为那些是指定元素祖先节点的选中元素:

1
$("p").has("a[href]")         //包含链接的段落

add()方法会扩充选区,而不是对其进行过滤或提取。可以将传给$()函数的任何参数(除了函数)照样传给add()方法。add()方法会返回 原来的选中元素,加上传给$()函数的那些参数所选中(或创建)的那些元素。add()会移除重复元素,并对该组合选区进行排序,以便里面的元素按照文档 中的顺序排列:

1
2
3
4
5
6
//选取所有<div>和所有<P>元素的等价方式
$("div, p") //使用选择器组
$("div").add(p) //给add()传入选择器
$("div").add($("p")) //给add()传入jQuery对象
var paras = document.getElementsByTagName("p"); //类数组对象
$("div").add(paras); //给add()传入元素数组

将选中元素集用做上下文

上面描述的filter(). add()、和not()方法会在各自的选中元素集上执行交集、并集和差集运算。jQuery还定义一些其他选取方法可将当前选中元素集作为上下文来使 用。对选中的每一个元素,这些方法会使用该选中元素作为上下文或起始点来得到新的选中元素集,然后返回一个新的jQuery对象,包含所有新的选中元素的 并集。与add()方法类似,会移除重复元素并进行排序,以便元素会按照在文档中出现的顺序排列好。

该类别选取方法中最通用的是find()。它会在每一个当前选中元素的子孙元素中寻找与指定选择器字符串匹配的元素,然后它返回一个新的 jQuery对象来代表所匹配的子孙元素集。注意这些新选中的元素不会并入已存在的选中元素集中。同时注意find()和filter()不 同,filter()不会选中新元素,只是简单地将当前选中的元素集进行缩减:

1
$("div").find("p")            //在中查找元素,与$("div p")相同

该类别中的其他方法返回新的jQuery对象,代表当前选中元素集中每一个元素的子元素、兄弟元素或父元素。大部分都接受可选的选择器字符串作为参数。不传入选择器时,它们会返回所有子元素、兄弟元素或父元素。传入选择器时,它们会过滤元素集,仅返回匹配的。

children()方法返回每一个选中元素的直接子元素,可以用可选的选择器参数进行过滤:

1
2
3
//寻找id为"header"和"footer"元素的子节点元素中的所有<span>元素
//与$("#header>span, #footer>span")相同
$("#header, #footer").children("span")

contents()方法与children()方法类似,不同的是它会返回每一个元素的所有子节点,包括文本节点。如果选中元素集中 有<iframe>元素,contents()还会返回该<iframe>内容的文档对象。注意contents()不接受可选 的选择器字符串参数—因为它返回的文档节点不完全是元素,而选择器字符串仅用来描述元素节点。
next()和prev()方法返回每一个选中元素的下一个和上一个兄弟元素(如果有的话)。如果传入了选择器,会只选中匹配该选择器的兄弟元素:

1
2
$("h1").next("p")      //与$("h1+p")相同
$("h1").prev() //<h1>元素前面的兄弟元素

nextAll()和prevAll()返回每一个选中元素前面或后面的所有兄弟元素(如果有的话)。siblings()方法则返回每一个选中元素的所有兄弟元素(选中元素本身不是自己的兄弟元素)。如果给这些方法传人选择器,则只会返回匹配的兄弟元素:

1
2
$("#footer").nextAll("p")       //紧跟#footer元素的所有<P>兄弟元素
$("#footer").prevAll() //#footer元素前面的所有兄弟元素

恢复到之前的选中元素集

为了实现方法的链式调用,很多jQuery对象的方法最后都会返回调用对象。然而本节讲述的方法都返回新的jQuery对象。可以链式调用下去,但必须清晰地意识到,在链式调用的后面所操作的元素集,可能已经不是该链式调用开始时的元素集了。

实际情况还要复杂些。当这里所描述的选取方法在创建或返回一个新的ejQuery对象时,它们会给该对象添加一个到它派生自的旧jQuery对象的 内部引用。这会创建一个jQuery对象的链式表或栈。end()方法用来弹出栈,返回保存的jQuery对象。在链式调用中调用end()会将匹配元素 集还原到之前的状态。考虑以下代码:

1
2
3
4
5
6
7
8
9
10
11
12
//寻找所有<div>元素,然后在其中寻找<P>元素
//高亮显示<P>元素,然后给<div>元素添加一个边框
//首先,不使用链式调用
var divs = $("div");
var paras = div.find("p");
paras.addClass("highlight");
divs.css("border", "solid black 1px");

//下面展现如何使用链式调用来实现
$("div").find("p").addClass("highlight").end().css("border", "solid black 1px");
//还可以将操作调换顺序来避免调用end()
$("div").css("border", "solid block 1px").find("p").addClass("highlight");

如果想手动定义选中元素集,同时保持与end()方法的兼容,可以将新的元素集作为数组或类数组对象传递给push5tack()方法。指定的元素会成为新的选中元素,之前选中的元素集则会压入栈中,之后可以用end()方法还原它们:

1
2
3
var sel = $("div");             //选取所有<div>元素
sel.pushStack(document.getElementsByTagName("p")); //修改为所有<P>元素
sel.end(); //还原为<div>元素

Adhere to original technology sharing, your support will encourage me to continue to create!