选择器是jQuery的根基,在jQuery中,对事件处理、遍历DOM和Ajax操作都依赖于选择器。
2.1 jQuery选择器是什么
1.CSS选择器
CSS是一项出色的技术,它使得网页的结构和表现样式完全分离。利用CSS选择器能轻松地对某个元素添加样式而不改动HTML结构,只需通过添加不同的CSS规则,就可以得到各种不同样式的网页。它为在获取目标元素之后施加样式提供了极大的灵活性。常用的CSS选择器分类如表
几乎所有主流浏览器都支持上面这些常用的选择器。此外CSS中还有伪类选择器(E:Pseudo-Elements{ CssRules })、子选择器(E > F{ CssRules })、临近选择器(E + F { CssRules })和属性选择器(E [ attr ] { CssRules })等。但遗憾的是,主流浏览器并非完全支持所有的CSS选择器。
更加详细的介绍可以参考http://www.w3.org/TR/CSS2/selector.html网址。
注:把CSS应用到网页中有3种方式,即行间样式表、内部样式表和外部样式表。
2.jQuery选择器
jQuery中的选择器完全继承了CSS的风格。利用jQuery选择器,可以非常便捷和快速地找出特定的DOM元素,然后为它们添加相应的行为,而无需担心浏览器是否支持这一选择器。学会使用选择器是学习jQuery的基础,jQuery的行为规则都必须在获取到元素后才能生效。
下面来看一个简单的例子,代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<script type="text/javascript">
function demo(){
alert('JavaScript demo.');
}
</script>
</head>
<body>
<p onClick="demo();">Click me.</p>
</body>
</html>
本段代码的作用是为<p>元素设置一个onclick事件,当单击此元素时,会弹出一个对话框,显示效果如图
像上面这样把JavaScript代码和HTML代码混杂在一起的做法同样也非常不妥,因为它并没有将网页内容和行为分离,所以建议使用下面的方法,代码如下:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>jQuery demo</title>
<script src="file:///D|/jQuery/scripts/jquery-3.4.0.js"></script>
</head>
<body>
<p class="demo">jQuery Demo</p>
<script type="text/javascript">
$(".demo").click(function(){ //给class为demo的元素添加行为
alert("jQuery demo!");
});
</script>
</body>
</html>
此时,可以对CSS的写法和jQuery的写法进行比较。
CSS获取到元素的代码如下:
.demo{ //给class为demo的元素添加样式
⋯
}
jQuery获取到元素的代码如下:
$(".demo").click(function(){ //给class为demo的元素添加行为
⋯
jQuery选择器的写法与CSS选择器的写法十分相似,只不过两者的作用效果不同,CSS选择器找到元素后是添加样式,而 jQuery 选择器找到元素后是添加行为。jQuery中涉及操作CSS样式的部分比单纯的CSS功能更为强大,并且拥有跨浏览器的兼容性。
2.2jQuery选择器的优势
1.简洁的写法
$()函数在很多 JavaScript 类库中都被作为一个选择器函数来使用,在 jQuery 中也不例外。其中,$("#ID")用来代替document.getElementById()函数,即通过ID获取元素;$("tagName")用来代替document.getElementsByTagName()函数,即通过标签名获取HTML元素;
2.支持CSS 1到CSS 3选择器
jQuery选择器支持CSS 1、CSS 2的全部和CSS 3的部分选择器,同时它也有少量独有的选择器。
使用CSS选择器时,开发人员需要考虑主流浏览器是否支持某些选择器。而在jQuery中, 开发人员则可以放心地使用jQuery选择器而无需考虑浏览器是否支持这些选择器。
注意:为了能有更快的选择器解析速度,从1.1.3.1版以后,jQuery废弃了不常使用的XPath选择器,但在引用相关插件后,依然可以支持XPath选择器。
3.完善的处理机制
使用jQuery选择器不仅比使用传统的getElementById()和getElementsByTagName()函数简洁得多,而且还能避免某些错误。看下面这个例子,代码如下:
<div>test</div>
<script type="text/javascript">
document.getElementById("tt").style.color="red";
</script>
运行上面的代码,浏览器就会报错,原因是网页中没有id为“tt”的元素。
改进后的代码如下:
<div>test</div>
<script type="text/javascript">
if(document.getElementById("tt")){
document.getElementById("tt").style.color="red";
}
</script>
使用jQuery获取网页中不存在的元素也不会报错,看下面的例子,代码如下:
<div>test</div>
<script type="text/javascript">
$('#tt').css("color","red"); //这里无需判断$('#tt')是否存在
</script>
有了这个预防措施,即使以后因为某种原因删除网页上某个以前使用过的元素,也不用担心这个网页的JavaScript代码会报错。
需要注意的是,$('#tt')获取的永远是对象,即使网页上没有此元素。因此当要用jQuery检查某个元素在网页上是否存在时,不能使用以下代码:
if ( $("#tt") ) {
//do something
}
而应该根据获取到元素的长度来判断,代码如下:
if ( $("#tt").length > 0 ) {
//do something
}
或者转化成DOM对象来判断,代码如下:
if ( $("#tt")[0] ) {
//do something
}
2.3 jQuery选择器
在正式学习jQuery选择器之前,先看几组用传统的JavaScript方法获取页面中的元素,然后给元素添加行为事件的例子。
例子1:给网页中的所有<p>元素添加onclick事件。
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>javaScprit demo</title>
</head>
<body>
<p>测试1</p >
<p>测试2</p >
<script type="text/javascript">
var items = document.getElementsByTagName("p");//获取网页中所有的p元素
for(var i=0;i < items.length;i++){ //由于获取的是数组对象,因此需要把它循环出来
items[i].onclick = function(){ //给每个对象添加onclick事件
alert("hello");//doing something
}
}
</script>
</body>
</html>
例子2:使一个特定的表格隔行变色。
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>javascript demo</title>
</head>
<body>
<table id="tb">
<tbody>
<tr><td>第一行</td><td>第一行</td></tr>
<tr><td>第二行</td><td>第二行</td></tr>
<tr><td>第三行</td><td>第三行</td></tr>
<tr><td>第四行</td><td>第四行</td></tr>
<tr><td>第五行</td><td>第五行</td></tr>
<tr><td>第六行</td><td>第六行</td></tr>
</tbody>
</table>
<script type="text/javascript">
var item = document.getElementById("tb"); //获取id为tb的元素(table)
var tbody = item.getElementsByTagName("tbody")[0]; //获取表格的第1个tbody元素
var trs = tbody.getElementsByTagName("tr"); //获取tbody元素下的所有tr元素
for(var i=0;i < trs.length;i++){ //循环tr元素
if(i%2==0){ //取模
trs[i].style.backgroundColor = "#888"; //改变符合条件的tr元素的背景色
}
}
</script>
</body>
</html>
例子3:对多选框进行操作,输出选中的多选框的个数。
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>javascript demo</title>
</head>
<body>
<input type="checkbox" value="1" name="check" checked="checked"/>
<input type="checkbox" value="2" name="check" />
<input type="checkbox" value="3" name="check" checked="checked"/>
<input type="button" value="你选中的个数" id="btn"/>
<script type="text/javascript">
var btn = document.getElementById("btn"); //获取id为btn的元素(button)
btn.onclick = function(){ //给元素添加onclick事件
var arrays = new Array(); //创建一个数组对象
var items = document.getElementsByName("check");
//获取name为check的一组元素(checkbox)
for(i=0; i<items.length; i++){ //循环这组数据
if(items[i].checked){ //判断是否选中
arrays.push(items[i].value); //把符合条件的数据添加到数组中
//push()是JavaScript数组中的方法
}
}
alert( "选中的个数为:"+arrays.length )
}
</script>
</body>
</html>
下面学习如何使用jQuery获取这些元素。
jQuery选择器分为基本选择器、层次选择器、过滤选择器和表单选择器。
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>javascript demo</title>
<style type="text/css">
div,span,p{
width:140px;
height:140px;
margin:5px;
background:#aaa;
border:#000 1px solid;
float:left;
font-size:17px;
font-family:Verdana;
}
div.mini{
width:55px;
height:55px;
background-color:#aaa;
font-size:12px;
}
div.hide{
display:none;
}
</style>
</head>
<body>
<div class="one" id="one" >
id为one,class为one的div
<div class="mini">class为mini</div>
</div>
<div class="one" id="two" title="test" >
id为two,class为one,title为test的div.
<div class="mini" title="other">class为mini,title为other</div>
<div class="mini" title="test">class为mini,title为test</div>
</div>
<div class="one">
<div class="mini">class为mini</div>
<div class="mini">class为mini</div>
<div class="mini">class为mini</div>
<div class="mini"></div>
</div>
<div class="one">
<div class="mini">class为mini</div>
<div class="mini">class为mini</div>
<div class="mini">class为mini</div>
<div class="mini" title="tesst">class为mini,title为tesst</div>
</div>
<div style="display:none;" class="none">
style的display为"none"的div
</div>
<div class="hide">class为"hide"的div</div>
<div>
包含input的type为"hidden"的div<input type="hidden" size="8"/>
</div>
<span id="mover">正在执行动画的span元素.</span>
</body>
</html>
2.3.1 基本选择器
通过元素id、class和标签名等来查找DOM元素。在网页中,每个id名称只能使用一次,class允许重复使用。基本选择器的介绍说明如表
可以使用这些基本选择器来完成绝大多数的工作。下面用它们来匹配刚才 HTML 代码中的<div>,<span>等元素并进行操作(改变背景色),示例如表
2.3.2 层次选择器
通过DOM元素之间的层次关系来获取特定元素,例如后代元素、子元素、相邻元素和同辈元素等。层次选择器的介绍说明如表
继续沿用刚才例子中的HTML和CSS 代码,然后用层次选择器来对网页中的<div>,<span>等元素进行操作,示例如表
在层次选择器中,第1个和第2个选择器比较常用,而后面两个因为在jQuery里可以用更加简单的方法代替,所以使用的几率相对少些。
可以使用next()方法来代替$('prev + next')选择器,如表
可以使用nextAll()方法来代替$('prev~siblings')选择器,如表
siblings()方法与$('prev~siblings')选择器比较,$("#prev~div")选择器只能选择“prev”元素后面的同辈<div>元素。而 siblings()方法与前后位置无关,只要是同辈节点就都能匹配。
//选取#prev之后的所有同辈div元素
$("#prev ~ div").css("background","#bbffaa");
//同上
$("#prev").nextAll("div").css("background","#bbffaa");
//选取#prev所有的同辈div元素,无论前后位置
$("#prev").siblings("div").css("background","#bbffaa");
2.3.3 过滤选择器
通过特定的过滤规则来筛选出所需的DOM元素,过滤规则与 CSS中的伪类选择器语法相同,即选择器都以一个冒号(:)开头。按照不同的过滤规则,过滤选择器可以分为基本过滤、内容过滤、可见性过滤、属性过滤、子元素过滤和表单对象属性过滤选择器。
1.基本过滤选择器
接下来,使用这些基本过滤选择器来对网页中的<div>,<span>等元素进行操作,示例如表
2.内容过滤选择器
内容过滤选择器的过滤规则主要体现在它所包含的子元素或文本内容上。内容过滤选择器的介绍说明如表
接下来使用内容过滤选择器来操作页面中的元素,示例如表
3.可见性过滤选择器
可见性过滤选择器是根据元素的可见和不可见状态来选择相应的元素。可见性过滤选择器的介绍说明如表
在例子中使用这些选择器来操作DOM元素,示例如表
在可见性选择器中,需要注意选择器:hidden,它不仅包括样式属性display为“none”的元素,也包括文本隐藏域(<input type="hidden" />)和visibility:hidden之类的元素。
注意:show()是jQuery的方法,它的功能是显示元素,3000是时间,单位是毫秒。
4.属性过滤选择器
通过元素的属性来获取相应的元素。属性过滤选择器的介绍说明如表
接下来使用属性过滤选择器来对<div>和<span>等元素进行操作,示例如表
jQuery属性选择器的过滤规则比较多,特别容易混淆。为此,我把几个容易混淆的单独做了一个例子,以加强印象。HTML代码如下:
<div title="en">title为en的div元素</div>
<div title="en-UK">title为en-UK的div元素</div>
<div title="english">title为english的div元素</div>
<div title="en uk">title为en uk的div元素</div>
<div title="uken">title为uken的div元素</div>
生成的效果图
现在用jQuery的表单过滤选择器来操作它们,示例如表
5.子元素过滤选择器
子元素过滤选择器的介绍说明如表
:nth-child()选择器是很常用的子元素过滤选择器,详细功能如下。
(1):nth-child(even)能选取每个父元素下的索引值是偶数的元素。
(2):nth-child(odd)能选取每个父元素下的索引值是奇数的元素。
(3):nth-child(2)能选取每个父元素下的索引值等于2的元素。
(4):nth-child(3n)能选取每个父元素下的索引值是3的倍数的元素,(n从1开始)。
(5):nth-child(3n+1)能选取每个父元素下的索引值是(3n+1)的元素。(n从1开始)
接下来利用刚才所讲的选择器来改变<div>元素的背景色,示例如表
注意:eq(index)只匹配一个元素,而:nth-child 将为每一个符合条件的父元素匹配子元素。同时应该注意到 nth-child(index)的index是从 1 开始的,而:eq(index)是从 0 开始的。同理:first和:first-child,:last和:last-child也类似。
6.表单对象属性过滤选择器
此选择器主要是对所选择的表单元素进行过滤,例如选择被选中的下拉框,多选框等元素。表单对象属性过滤选择器的介绍说明如表
为了演示这些选择器,需要制作一个包含表单的网页,里面要包含文本框、多选框和下拉列表,HTML代码如下:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>javascript demo</title>
<script src="file:///D|/jQuery/scripts/jquery-3.4.0.js"></script>
<style type="text/css">
</style>
</head>
<body>
<form id="form1" action="#">
可用元素:<input name="add" value="可用文本框"/> <br/>
不可用元素:<input name="email" disabled="disabled" value="不可用文本框"/><br/>
可用元素: <input name="che" value="可用文本框" /><br/>
不可用元素:<input name="name" disabled="disabled" value="不可用文本框"/><br/>
<br/>
多选框:<br/>
<input type="checkbox" name="newsletter" checked="checked" value="test1" />test1
<input type="checkbox" name="newsletter" value="test2" />test2
<input type="checkbox" name="newsletter" value="test3" />test3
<input type="checkbox" name="newsletter" checked="checked" value="test4" />test4
<input type="checkbox" name="newsletter" value="test5" />test5
<div></div>
<br/><br/>
下拉列表1:<br/>
<select name="test" multiple="multiple" style="height:100px">
<option>浙江</option>
<option selected="selected">湖南</option>
<option>北京</option>
<option selected="selected">天津</option>
<option>广州</option>
<option>湖北</option>
</select>
<br/><br/>
下拉列表2:<br/>
<select name="test2" >
<option>浙江</option>
<option>湖南</option>
<option selected="selected">北京</option>
<option>天津</option>
<option>广州</option>
<option>湖北</option>
</select>
<div></div>
</form>
</body>
</html>
生成的效果图如图
现在用jQuery的表单过滤选择器来操作它们,示例如表
2.3.4 表单选择器
表单选择器的介绍说明如表
下面把这些表单选择器运用到下面的表单中,对表单进行操作。
表单HTML代码如下:
<form id="form1" action="#">
<input type="button" value="Button"/><br/>
<input type="checkbox" name="c"/>1
<input type="checkbox" name="c"/>2
<input type="checkbox" name="c"/>3<br/>
<input type="file" /><br/>
<input type="hidden" /><div style="display:none">test</div><br/>
<input type="image" /><br/>
<input type="password" /><br/>
<input type="radio" name="a"/>1<input type="radio" name="a"/>2<br/>
<input type="reset" /><br/>
<input type="submit" value="提交"/><br/>
<input type="text" /><br/>
<select><option>Option</option></select><br/>
<textarea></textarea><br/>
<button>Button</button><br/>
</form>
如果想得到表单内表单元素的个数,代码如下:
$("#form1 :input").length; //注意与$("#form1 input")的区别
如果想得到表单内单行文本框的个数,代码如下:
$("#form1 :text").length;
如果想得到表单内密码框的个数,代码如下:
$("#form1 :password").length;
同理,其他表单选择器的操作与此类似。
2.4应用jQuery改写示例
在本文开头部分,使用传统的JavaScript方法编写了3个简单的例子。
例子1:给网页中所有的<p>元素添加onclick事件。
例子2:使一个特定的表格隔行变色。
例子3:对多选框进行操作,输出选中的多选框的个数。
下面利用jQuery选择器以及隐式迭代的特性来重写这3个例子。
使用jQuery选择器重写例子1,代码如下。
$("p").click(function(){ //获取页面中的所有p元素,给每一个p元素添加单击事件
//doing something
})
使用jQuery选择器重写例子2,代码如下:
$("#tb tbody tr:even").css("backgroundColor","#888");
/*
获取id为tb的元素,然后寻找它下面的tbody标签,再寻找tbody下索引值是偶数的tr元素,改变它的背景色。
css("property","value"):用来设置jQuery对象的样式
*/
使用jQuery选择器重写例子3,代码如下:
$("#btn").click(function(){
//先使用属性选择器,然后用表单对象属性过滤,最后获取jQuery对象的长度
var items = $("input[name='check']:checked");
alert( "选中的个数为:"+ items.length );
});
2.5选择器中的一些注意事项
2.5.1 选择器中含有特殊符号的注意事项
1.选择器中含有“· ”、“#”、“(”或“]”等特殊字符,使用转义字符
根据W3C的规定,属性值中是不能含有这些特殊字符的,但在实际项目中偶尔会遇到表达式中含有“#”和“.”等特殊字符,如果按照普通的方式去处理出来的话就会出错。解决此类错误的方法是使用转义符转义。
HTML代码如下:
<div id="id#b">bb</div>
<div id="id[1]">cc</div>
正确的写法如下:
$("#id\\#b"); //转义特殊字符“#”
$("#id\\[1\\]"); //转义特殊字符“[ ]”
2.属性选择器的@符号问题
在jQuery升级版本过程中,jQuery在1.3.1版本中彻底放弃了1.1.0版本遗留下的@符号,假如你使用1.3.1以上的版本,那么你不需要在属性前添加@符号,比如:
$(〝 div[@title='test‘] "];
正确的写法是去掉@符号,比如:
$(〝 div[title='test‘] "];
注意:如果你的项目中已使用较早的jQuery代码和插件,若把jQuery升级到最新后,出现代码报错或不能运行,那么很有可能是因为代码中使用了属性选择器的@符号而引起的。
2.5.2 选择器中含有空格的注意事项
选择器中的空格也是不容忽视的,多一个空格或少一个空格也许会得到截然不同的结果。
看下面这个例子,它的HTML代码如下:
<div class="test">
<div style="display:none;">aa</div>
<div style="display:none;">bb</div>
<div style="display:none;">cc</div>
<div class="test" style="display:none;">dd</div>
</div>
<div class="test" style="display:none;">ee</div>
<div class="test" style="display:none;">ff</div>
使用如下的jQuery选择器分别获取它们。
var $t_a = $('.test :hidden'); //带空格的JQuery选择器
var $t_b = $('.test:hidden'); //不带空格的JQuery选择器
var len_a = $t_a.length;
var len_b = $t_b.length;
alert("$('.test :hidden') = "+len_a); //输出 4
alert("$('.test:hidden') = "+len_b); /输出 3
之所以会出现不同的结果,是因为后代选择器与过滤选择器的不同。
var $t_a = $('.test :hidden'); //带空格的
以上代码是选取class为“test”的元素里面的隐藏元素。
而代码:
var $t_b = $('.test:hidden'); //不带空格的
则是选取隐藏的class为“test”的元素。
2.6案例研究—某网站品牌列表的效果
以下是某网站上的一个品牌列表的展示效果,用户进入该页面时,品牌列表默认是精简显示的(即不完整的品牌列表),如图
用户可以单击商品列表下方的“显示全部品牌”按钮来显示全部的品牌。
单击“显示全部品牌”按钮的同时,列表会将推荐的品牌的名字高亮显示,按钮里的文字也换成了“精简显示品牌”,如图
再次单击“精简显示品牌”按钮,即又回到第一副图所示的页面。
HTML代码如下:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>javascript demo</title>
<script src="file:///D|/jQuery/scripts/jquery-3.4.0.js"></script>
<style type="text/css">
.SubCategoryBox{
width:90%;
height:350px;
color:#000;
border:solid 2px #000;
position:relative;
}
ul{
list-style-type:none;
margin:100;
width:100%;
color:#000;
}
ul li{
width:350px;
magin:50px;
float:left;
}
.SubCategoryBox div{
border:solid 1px #666;
color:#000;
width:150px;
height:40px;
margin:100px auto;
text-align:center;
background: url(images/down.png) top no-repeat;
}
a{
text-decoration:none;
}
</style>
</head>
<body>
<div class="SubCategoryBox">
<ul>
<li><a href="#">佳能</a><i>(30440) </i></li>
<li><a href="#">索尼</a><i>(27220) </i></li>
<li><a href="#">三星</a><i>(20808) </i></li>
<li><a href="#">尼康</a><i>(17821) </i></li>
<li><a href="#">松下</a><i>(12289) </i></li>
<li><a href="#">卡西欧</a><i>(8242) </i></li>
<li><a href="#">富士</a><i>(14894) </i></li>
<li><a href="#">柯达</a><i>(9520) </i></li>
<li><a href="#">宾得</a><i>(2195) </i></li>
<li><a href="#">理光</a><i>(4114) </i></li>
<li><a href="#">奥林巴斯</a><i>(12205) </i></li>
<li><a href="#">明基</a><i>(1466) </i></li>
<li><a href="#">爱国者</a><i>(3091) </i></li>
<li><a href="#">其他品牌相机</a><i>(7275) </i></li>
</ul>
<div class="showmore">
<a href="more.html"><span>显示全部品牌</span></a>
</div>
</div>
</body>
</html>
接下来为这个页面添加一些交互效果,要做的工作有以下几项:
(1)从第7条开始隐藏后面的品牌(最后一条“其它品牌相机”除外)。
var $category = $(〝ul li:gt(5):not(:last)");
$category.hide(); // 隐藏上面获取到的jQuery对象
$('ul li:gt(5):not(:last)')的意思是先获取<ul>元素下索引值大于5的<li>元素的集合元素,然后去掉集合元素中的最后一个元素。这样,即可将从第7条开始至倒数第2条的所有品牌都获取到。最后通过hide()方法隐藏这些元素。
(2)当用户单击“显示全部品牌”按钮时,执行以下操作。
首先获取到按钮:
var $toggleBtn = $('div.showmore > a');
//功能:获取“显示全部品牌”按钮
//意思:class为showmore的div的所有子元素a
//然后给按钮添加事件,使用show()方法把隐藏的品牌列表显示出来:
$toggleBtn.click(function(){
$category.show(); //显示全部品牌
return false; //超链接不跳转
});
由于给超链接添加onclick事件,因此需要使用“return false”语句让浏览器认为用户没有单击该超链接,从而阻止该超链接跳转。
之后,需要将“显示全部品牌”按钮文本切换成“精简显示品牌”:
$(this).find("span")
.css("background","url(images/up.gif) no-repeat 0 0")
.text("精简显示品牌"); //这里使用了链式操作
这里完成了两步操作,即把按钮的背景图片换成向上的图片,同时也改变了按钮文本内容,将其替换成“精简显示品牌”。
接下来需要高亮推荐品牌:
$(〝ul li")
.filter(":contains('佳能'),:contains('尼康'),:contains('奥林巴斯')")
.addClass("promoted"); //添加高亮样式
使用filter()方法筛选出符合要求的品牌,然后为它们添加promoted样式。在这里推荐了3个品牌,即佳能、尼康和奥林巴斯。
此时,完成的jQuery代码如下:
$(function(){ //等待DOM加载完毕
var $category = $('ul li:gt(5):not(:last)');
//获得索引值大于5的品牌集集合对象(除最后一条)
$category.hide(); //隐藏上面获取到的jQuery对象
var $toggleBtn = $('div.showmore > a'); //获取“显示全部品牌”按钮
$toggleBtn.click(function(){
$category.show(); //显示$category
$(this).find('span')
.css("background","url(images/up.gif) no-repeat 0 0")
.text("精简显示品牌"); //改变背景图片和文本
$('ul li').filter(":contains('佳能'),:contains('尼康'),:contains('奥林巴斯')")
.addClass("promoted"); //添加高亮样式
return false; //超链接不跳转
})
})
运行上面的代码,单击“显示全部品牌”按钮后,显示下图所示的效果
注意:上面代码中用到的几个jQuery方法的意思如下:
show():显示隐藏的匹配元素。
css(name,value):给元素设置样式。
text(string):设置所有匹配元素的文本内容。
filter(expr):筛选出与指定表达式匹配的元素集合,其中expr可以是多个选择器的组合。注意区分它和find()方法。find()会在元素内寻找匹配元素,而filter()则是筛选元素。一个是对它的子集操作,一个是对自身集合元素进行筛选。
addClass(class):为匹配的元素添加指定的类名。
(3)当用户单击“精简显示品牌”按钮时,将执行以下操作。
由于用户单击的是同一个按钮,因此事件仍然是在刚才的按钮元素上。要将切换两种状态的效果在一个按钮上进行,可以通过判断元素的显示或者隐藏来达到目的。
在jQuery中,与show()方法相反的是hide()方法,因此可以使用hide()方法将品牌隐藏起来,代码如下:
$category.hide(); //隐藏$category
然后将“精简显示品牌”按钮文本切换成“显示全部品牌”,同时按钮图片换成向下的图片,这一步与前面类似,只不过是图片路径和文本内容不同而已,代码如下:
$(this).find('span')
.css("background","url(img/down.gif) no-repeat 0 0")
.text("显示全部品牌"); //改变背景图片和文本
//接下来需要去掉所有品牌的高亮显示状态,此时可以使用 removeClass()方法来完成:
$('ul li').removeClass("promoted"); //去掉高亮样式
它将去掉所有<li>元素上的“promoted”样式,即去掉了品牌的高亮状态。
注意:removeClass(class)的功能和addClass(class)的功能正好相反。addClass(class)的功能是为匹配的元素添加指定的类,而removeClass(class)则是从匹配的元素中删除指定的类。
if($category.is(":visible")){ //如果元素显示
$category.hide(); //隐藏$category
$(this).find('span')
.css("background","url(images/down.gif) no-repeat 0 0")
.text("显示全部品牌"); //改变背景图片和文本
$('ul li').removeClass("promoted"); //去掉高亮样式
}else{
$category.show(); //显示$category
$(this).find('span')
.css("background","url(images/up.gif) no-repeat 0 0")
.text("精简显示品牌"); //改变背景图片和文本
$('ul li').filter(":contains('佳能'),:contains('尼康'),:contains('奥林巴斯')").addClass("promoted");
//添加高亮样式
}
至此任务完成,完整的jQuery代码如下:
$(function(){ //等待DOM加载完毕.
var $category = $('ul li:gt(5):not(:last)');
//获得索引值大于5的品牌集合对象(除最后一条)
$category.hide(); //隐藏上面获取到的jQuery对象
var $toggleBtn = $('div.showmore > a'); //获取“显示全部品牌”按钮
$toggleBtn.click(function(){ //给按钮添加onclick事件
if($category.is(":visible")){ //如果元素显示
$category.hide(); //隐藏$category
$(this).find('span')
.css("background","url(img/down.gif)no-repeat 0 0")
.text("显示全部品牌"); //改变背景图片和文本
$('ul li').removeClass("promoted"); //去掉高亮样式
}else{
$category.show(); //显示$category
$(this).find('span')
.css("background","url(img/up.gif)no-repeat 0 0")
.text("精简显示品牌"); //改变背景图片和文本
$('ul li').filter(":contains('佳能'),:contains('尼康'),:contains('奥林巴斯')").addClass("promoted");
//添加高亮样式
}
return false; //超链接不跳转
})
})
运行代码后,单击按钮,品牌列表会在“全部”和“精简”两种效果之间循环切换,显示效果如图2-10和图2-11所示。
图2-10 精简模式
图2-11 全部模式
在 jQuery 中有一个方法更适合上面的情况,它能给一个按钮添加一组交互事件,而不需要像上例一样去判断,上例的代码如下:
toggleBtn.click(function(){
if($category.is(":visible")){
//如果元素显示
//元素隐藏 代码①
}else{
//元素显示 代码②
}
})
如果改成toggle()方法,代码则可以直接写成以下形式:
$toggleBtn.toggle(function(){ //toggle()方法用来交替一组动作
//显示元素 代码③
},function(){
//隐藏元素 代码④
})
当单击按钮后,脚本会对代码③和代码④进行交替处理。
注意:在本例中,如果用户禁用了JavaScript的功能,品牌列表仍然能够完全显示,当用户单击“显示全部品牌”按钮的时候,会跳转到 more.html 页面来显示品牌列表。作为一名专业的开发者,必须要考虑到禁用或者不支持 JavaScript的浏览器(用户代理)。另外,这点对于搜索引擎优化也特别有帮助,毕竟当前的搜索引擎爬虫基本都不支持JavaScript。
2.7其他选择器
2.7.1 jQuery提供的选择器的扩展
虽然 jQuery 提供了许多实用的选择器,但还是有可能不能满足各种多变的业务需要,不过jQuery选择器是可以进一步扩展的。
1.MoreSelectors for jQuery
这是一个jQuery的插件,用于增加更多的选择器,例如.color可以匹配颜色,:colIndex可以匹配表格中的列,:focus可以匹配获取焦点的元素等。
插件地址:http://plugins.jquery.com/project/moreSelectors。
2.Basic XPath
这个插件可以让用户使用基本的XPath。jQuery最开始支持XPath选择器,但由于使用人数不多,且降低了选择器匹配的效率,因此在1.2以后的版本中取消了默认对XPath选择器的支持,改为通过插件来实现。
插件地址:http://plugins.jquery.com/project/xpath。2.7.2 其他使用CSS选择器的方法
除了 jQuery 提供了强大的选择器支持外,也有其他一些 JavaScript 脚本也提供了此类纯粹的CSS选择器的支持。
1.document.getElementsBySelector()
早在2003年,Simon Willison就编写了该脚本,它的作用是通过选择器来获取文档元素。读者可以通过以下代码获取元素。
document.getElementsBySelector('div#main p a.external')
该脚本最新版本为0.4版,更新日期为2003年3月25日。
发布地址:http://plugins.jquery.com/project/xpath。
2.cssQuery()
这是Dean Edwards编写的一款利用CSS选择器查找元素的脚本。支持所有CSS1、CSS2以及部分CSS3选择器,jQuery的选择器其实是源自于此,它支持一些jQuery尚不支持的选择器,例如 E:link、E:nth-last-child(n)、E:root、E:lang(fr)、E:target和E[foo|="bar"]等。语法结构如下:
elements = cssQuery(selector [, from]);
该脚本最新版本为2.0.2版,更新日期为2005年9月10日。
官方网站:http://dean.edwards.name/my/cssQuery/。
3.querySelectorAll()
这不是一个脚本库,而是W3C在Selectors API草案中提到的方法,该草案的最新版本是在2007年12月21日发布的。此方法也是用于实现通过CSS选择器来获取元素的。IE 8的Beta 2中已经率先实现了此方法。相信其他几大浏览器也很快就能实现此方法。
JQuery的作者 John Resig 也表示将会利用 querySelectorAll()这个浏览器原生的方法来重构jQuery的选择器,同时增加一些jQuery扩展的选择器,届时jQuery选择器的执行效率也将大大提高。
W3C Selectors API:http://www.w3.org/TR/selectors-api/。