尽管jQuery选择器能给我们灵活的方法识别出DOM中的复杂的元素,并能加以设置。但有时一些匹配条件却不能很好地用表达示表达出来。考虑到jQuery强有力的方法集合,我们期望调整匹配表达示和方法集合这两者之间的关系来解决这个问题。
某些情况下,jQuery提供的方法不会基于匹配的元素之上,但又可以与本身进行匹配相关的设置。比如:
add(表达示)
表达示可以是一个选择器表达示,它将得到一个相匹配的结果。当然也可以是一个新元素字符串。不管这个结果是直接引用的元素还是一个与表达示相匹配的元素,add()方法可以将调用该方法的匹配设定与之进行连接。就像这样:
$(’div’).add(’p').css(’color’,'red’);
在原有<div>元素的匹配关系中添加新匹配关系<p>,最后为这个匹配集合(所有的<div>和所有的<p>)再添加一个color=”red”的css属性。
你可能认为这有点多余,因为有效果一样的方法可以做到:
$(‘div,p’).css(‘color’,‘red’);
但有时我们必须要这样做。例如:
$(’div’).css(’font-weight’,'bold’).add(’p').css(’color’,'red’);
先为所有匹配的<div>元素加个字符粗体的样式,然后再加再入一个所有匹配的<p>元素,字体样式设为”red”。看起来能节省不少代码……
更多的例子:
$(’div’).add(someElement).css(’border’,'3px solid pink’);
$(’div’).add([element1,element2]).css(’border’,'3px solid pink’);
去除匹配的元素
当要从已经匹配的元素中去除一些元素,就要用到not()方法。与add()类似,也是创建一个新的匹配设置,但这个匹配设置的元素会被除外。可以声明一个jQuery选择器,也可以是一个指定的元素。例如:
$(’body *’).css(’font-weight’,'bold’).not(’p').css(’color’,'red’);
让所有的元素字体加粗,然后然除<p>元素之外的其它元素字体色设为”red”。
$(’body *’).css(’font-weight’,'bold’).not(anElement).css(’color’,'red’);
和之前讲的除外的做法一样,变量anElement不受第二个匹配的设置的影响,因此它的字体色不会被设为”red”。
注意,避免犯低级错误,不要将.net()方法与remove()方法混淆。一个是从匹配表达示的元素中去除元素,另一个是从DOM中删除元素。
寻找子元素
有时要在已经确定的元素中寻找特定的子元素,就要用到find()方法。
这有别于之前的审核方法,find()方法只接受一个选择器表达示作为它的工作依据。在匹配选择器表达示的元素集合中寻找子元素。任何匹配选择器表达示的源元素本身不在它的寻找范围内。例子:
$(’div’).css(’background-color’,'blue’).find(’img’).css(’border’,'1px solid aqua’);
前面部分很简单了,选取所有的<div>元素,并使其背景色为成”blue”。后面部分是在这些被选取的<div>元素中寻找<img>子元素,并为其加个”aqua”色的边框。注意是在被选取的<div>元素内寻找,其它的不属于寻找范围。
筛选匹配集合
filter()方法可以接受选择器表达示,也可以接受一个函数。当接受的是选择器表达示时,他的功能与not()方法相反,是保留匹配表达示的元素。当接受的是函数时,函数可以编历每一个元素并且决定一些选择器表达无法确定的元素的去留。
看看例子:
$(’.bashful’).show().filter(’img[src$=.gif]‘).attr(’title’,'Hi there!’);
选取class=”bashful”的元素,并设置这些元素为可视。然后在这些元素当中筛选出src属性以.gif结尾的<img>元素,再为筛选出的这些元素指定一个title=”Hi there!”的属性。
$(’img[src^=images/]‘).filter(function(){
return $(this).attr(’title’).match(/.+@.+\.com/)!= null;
}).hide();
在src属性以images/开头的<img>元素中,筛选出title属性匹配一个.com的电子邮件格式的所有元素。
切分匹配集合
基于匹配表达示元素位置上的切分,并创建新的匹配关系。
看例子:
$(’body *’).slice(3).hide();
选取body内的所有元素,然后创建一个新的匹配元素集合,集合中切分出第三个元素之后的所有元素。将使其隐含起来。
$(’body *’).slice(2,4).hide();
选取body内的所有元素,然后创建一个新的匹配元素集合,集合中从第二个元素之后,直到第四个元素被切分出来,并使其隐含。
我们发现eq(n)事实上就是slice(n,n+1)的简写方法。
匹配关系
我们也许经常要在元素之间的关系上建立一些匹配设置。下表是一些类似的方法:
方法名称 | 说明 |
children(表达示) | 选取在父级匹配元素中与表达示相匹配的所有子元素。 |
next(表达示) | 选取紧接着原匹配元素,并且同级别与表达示相区配的一个元素。 |
nextAll(表达示) | 选取紧接着原区配元素,并且同级别与表达示相匹配的所有元素。 |
parent(表达示) | 选取与表达式相匹配的元素的直接父级元素。 |
parents(表达示) | 选取与表达式相匹配的元素的所有父级元素。 |
prev(表达示) | 选取原匹配元素之前,并且同级别与表达示相区配的一个元素。 |
prevAll(表达示) | 选取原匹配元素之前,并且同级别与表达示相区配的所有元素。 |
siblings(表达示) | 选取与表达示相匹配的所有同级别的元素。 |
contents() | 选取包含有指定内容的所有元素。 |
所有的这些方法都可以接受筛选表达示。如果缺省呢?当然就没有进行任何筛选了……
元素转换
有时你可能要把相匹配的元素转换成其它的值。jQuery提供map()方达到这个目的。看一个例子,你可这样来获取name=”myForm”的表单的所有表单元素的值:
var values = $(’#myForm :input’).map(function(){
return $(this).val();
});
map()的回调函数返回一个jQuery对象实例,要将其转换成JavaScript的标准数组。你可以使用不带参数get()方法:
var values = $(’#myForm :input’).map(function(){
return $(this).val();
}).get();
这时返回的值是一个JavaScript数组,而不再是jQuery对象了。
控制链
之前的所有的方法都是在一层层地迭加匹配表达式,以达到想要的审核目的。但jQuery允许你“亮出”之前的匹配表达式。来看看end()方法。
$(’div’).add(’p').css(’color’,'red’);
之前已经使用过这个例子,匹配的<div>元素表达示的基础上再加一个匹配<p>元素的表达示。
$(’div’).add(’p').css(’color’,'red’).end().hide();
这时,当访问了.css()方法之后,end()方法将”亮出”原来的匹配的表达示,也就是匹配所有的<div>元素。然后将其隐含。事实上等同于:
$(’div’).add(’p').css(’color’,'red’);
$(’div’).hide();
还一个有用的方法,它能影响表达示集合链的的设置,就是andSelf()方法:
$(’div’).css(’background-color’,'yellow’).children(’img’).css(’border’,'4px ridge maroon’)
.andSelf().css(’margin’,'4em’);
选取所有的<div>元素,并设定其’background-color:yellow。然后在被选取的<div>元素中选取<img>子元素,并设其border:4px ridge maroon。最后,子元素<img>和父级元素<div>(原匹配表达式)合并起来,共同设置一个margin:4em的样式。
差不多了,就到这里吧。选择器毫无疑问的是jQuery的精华。你会发现了解选择器能更有效地进行WEB开发。本系列的BLOG是参考Bear Bibeault和Yehuda katz两位大师的《jQuery Selector》所写。原书PDF可以在此下载。也许我还没有真正理解原书的精髓,但我自从开始接触jQuery到现在的半年时间里,所感受到的所学到的并不仅仅是完成一个效果或show一个样式。如今,我甚至羞于面对三个月前用jQuery完成的那些项目……