JQuery文档

一、  认识jQuery

随着Web 2.0的兴起,JavaScript越来越受到重视,一系列的JavaScript库也蓬勃发展起来。从早期的Prototype、Dojo到2006年的jQuery,再到2007年的Ext JS,互联网正在掀起一场JavaScript风暴。jQuery以其独特优雅的姿态,始终处于这场风暴的中心,受到越来越多的人的追捧。

1.1           JavaScript和JavaScript库

1.1.1       JavaScript简介

在正式介绍jQuery之前,有必要先了解一下JavaScript。

JavaScript是Netscape公司开发的一种脚本语言(scripting language)。JavaScript的出现使得网页和用户之间实现了一种实时的、动态的和交互的关系,使网页包含更多活跃的元素和更加精彩的内容。JavaScript自身存在3个弊端,即复杂的文档对象模型(DOM),不一致的浏览器实现和缺乏便捷的开发、调试工具。

正当JavaScript从开发者的视线中渐渐隐去时,一种新型的基于JavaScript的Web技术-Ajax(AsynchronousJavaScript And XML,异步的JavaScript和XML)诞生了。而使人们真正认识到Ajax技术的强大的导火索是Google公司推出的一系列新型Web应用,例如Gmail、Google Suggest和Google Map等。互联网基于JavaScript的应用也越来越多,使JavaScript不再是一种仅仅用于制作Web页面的简单脚本。

1.1.2  JavaScript库作用及对比

为了简化JavaScript的开发,一些JavaScript库诞生了。JavaScript库封装了很多预定义的对象和实用函数,能帮助使用者轻松建立有高难度交互的Web2.0特性的富客户端页面,并且兼容各大浏览器。下面是目前几种流行的JavaScript库的介绍和对比。

Prototype:Prototype是最早成型的JavaScript库之一,对JavaScript的内置对象(例如String对象、Array对象等)做了大量的扩展。现在还有很多项目使用Prototype。Prototype可以看做是把很多好的、有用的JavaScript的方法组合在一起而形成的JavaScript库。使用者可以在需要的时候随时将其中的几段代码抽出来放进自己的脚本里。但是由于Prototype成型年代早,从整体上对于面向对象的编程思想把握不是很到位,导致了其结构的松散。不过现在Prototype也在慢慢改进。

Dojo:Dojo的强大之处在于Dojo提供了很多其他JavaScript库所没有提供的功能。例如离线存储的API、生成图标的组件、基于SVG/VML的矢量图形库和Comet支持等等。Dojo是一款非常适合企业级应用的JavaScript库,并且得到了IBM、SUN和BEA等一些大公司的支持。但是Dojo的缺点也是很明显的:学习曲线陡,文档不齐全,最严重的就是API不稳定,每次升级都可能导致已有的程序失效。但是自从Dojo的1.0.0版出现以后,情况有所好转。Dojo还是一个很有发挥潜力的库。

YUI:YUI是由Yahoo公司开发的一套完备的、扩展项良好的富交互网页程序工具集。YUI封装了一系列比较丰富的功能,例如DOM操作和Ajax应用等,同时还包括了几个核心的CSS文件。该库本身文档极其完备,代码编写也非常规范。

Ext JS:Ext JS常简称为Ext,原本是对YUI的一个扩展,主要用于创建前端用户界面,如今已经发展到可以利用包括jQuery在内的各种JavaScript框架作为基础库,而Ext作为界面的扩展库来使用。Ext可以用来开发富有华丽外观的富客户端应用,能使B/S应用更加具有活力。但是由于Ext侧重于界面,本身比较臃肿,所以使用之前请先权衡利弊。另外,需要注意的事,Ext并非完全免费,如果用于商业用途,需要付费获得授权许可。

MooTools:MooTools是一套轻量、简洁、模块化和面向对象的JavaScript框架。MooTools的语法几乎和Prototype一样,但却提供了更为强大的功能、更好的扩展性和兼容性。其模块化思想非常优秀,核心代码大小只有8KB。无论用到哪个模块都可及时导入,即使是完整版大小也不超过160KB。MooTools完全彻底的面向对象的编程思想,语法简洁直观,文档完善,是一个非常不错的JavaScript库。

jQuery:jQuery同样是一个轻量级的库,拥有强大的选择器,出色的DOM操作,可靠的事件处理、完善的兼容性和链式操作等功能。这些优点吸引了一批批的JavaScript开发者去学习它、研究它。

总之,每个JavaScript库都有各自的优点和缺点,同时也有各自的支持者和反对者。自从jQuery诞生那天起,其关注度就一直在稳步上升,jQuery已经逐渐从其他JavaScript库中脱颖而出,成为Web开发人员的最佳选择。

1.2 jQuery

1.2.1  jQuery简介

jQuery是继Prototype之后有一个优秀的JavaScript库,是一个由John Resig创建于2006年1月的开源项目。现在的jQuery团队主要包括核心库、UI和插件等开发人员以及推广和网站设计维护人员。团队中由3个核心人物:John Resig、Brandon Aaron 和 Jorn Zaefferer。

jQuery凭借简洁的语法和跨平台的兼容性,极大地简化了JavaScript开发人员遍历HTML文档、操作DOM、处理事件、执行动画和开发Ajax的操作。其独特而又优雅的代码风格改变了JavaScript程序员的设计思路和编写程序的方式。总之,无论是网页设计师、后台开发者、业余爱好者是项目管理者,也无论是JavaScript初学者还是JavaScript高手,都又足够都的理由去学习jQuery。

1.2.2  jQuery的优势

jQuery强调的理念是写的少,做得多(write less,do more)。jQuery独特的选择器、链式的DOM操作、事件处理机制和封装完善的Ajax都是其他JavaScript库望尘莫及的。概括起来,jQuery有以下优势。

(1)轻量级。

jQuery非常轻巧,采用Dean Edwards编写的Parker压缩后,大小不到30KB。如果使用Min版并且在服务器启用Gzip压缩后,大小只有18KB。

(2)强大的选择器。

jQuery允许开发者使用从CSS1到CSS3几乎所有的选择器,以及jQuery独创的高级而复杂的选择器。另外还可以加入插件使其支持XPath选择器,甚至开发者可以编写属于自己的选择器。由于jQuery支持选择器这一特性,因此有一定CSS经验的开发人员可以很容易地切入到jQuery的学习中来。

(3)出色的DOM操作的封装。

jQuery封装了大量常用的DOM操作,使开发者在编写DOM操作相关程序的时候能够得心应手。JQuery轻松地完成各种原本非常复杂的操作,让JavaScript新手也能写出出色的程序。

(4)可靠的事件处理机制

吸取了JavaScript专家Dean Edwards编写的事件处理函数的精华,使得jQuery在处理事件绑定的时候相当可靠。在预留退路(graceful degradation)、循序渐进以及非入侵式(Unobtrusive)编程思想方法,jQuery也做的非常不错。

(5)完善的Ajax

jQuery将所有的Ajax操作封装到一个函数$.ajax()里,使得开发者处理Ajax的时候能够专心处理业务逻辑而无需关心复杂的浏览器兼容性和XMLHttpRequest对象的创建和使用的问题。

(6)不污染顶级变量。

jQuery只建立一个名为jQuery的对象,其所有的函数方法都在这个对象之下。其别名$也可以随时交出控制权,绝对不会污染其他的对象。该特性使jQuery可以与其他JavaScript库共存,在项目中放心的引用而不需要考虑到后期可能的冲突。

(7)出色的浏览器兼容性。

作为一个流行的JavaScript库,浏览器的兼容性是必须具备的条件之一。jQuery能够在IE6.0+、FF2+、Safari2.0+和Opera9.0+下正常运行。jQuery同时修复了一些浏览器之间的差异,是开发者不必在开展项目前建立浏览器兼容性。

(8)链式操作方式。

jQuery中最有特色的莫过与它的链式操作方式——即对发生在同一个jQuery对象上的一组动作,可以直接连接写而无需重复获取对象。这一特点使jQuery的代码无比优雅。

(9)隐式迭代

当用jQuery找到带有“.myClass”类的全部元素,然后隐藏它们时,无需循环遍历每一个返回的元素。相反,jQuery里的方法都被设计成自动操作对象的对象集合,而不是单独的对象,这使得大量的循环结构变得不再必要,从而大幅地减少了代码量。

(10)行为层与结构层的分离。

开发者可以使用jQuery选择器选中元素,然后直接给元素添加事件。这种将行为层与结构层完全分离的思想,可以使jQuery开发人员和HTML或其他页面开发人员各司其职,摆脱过去开发冲突或个人单干的开发模式。同时,后期维护也非常方便,不需要在HTML代码中寻找某些函数和重复修改HTML代码。

(11)丰富的插件支持。

jQuery的易扩展性,吸引了来自全球的开发者来编写jQuery的扩展插件。目前已经有超过几百种的官方插件支持,而且还不断有新插件面世。

 (12)完善文档。

jQuery的文档非常丰富,现阶段多为英文文档,中文文档相对较少。很多热爱jQuery团队都在努力完善jQuery的中文文档,例如jQuery的中文API,图灵教育的翻译的《Learning jQuery》等等。

(13)开源。

jQuery是一个开源的产品,任何人都可以自由地使用并提出改进意见。

1.3 jQuery代码的编写

JQuery不需要安装,把下载的jquery-1.4.1.js放到网站上的一个公共的位置,想要在某各页面上使用jQuery时,只需要在相关的HTML文档中引入该库文件即可。在实际项目中,读者可以根据实际需要调整jQuery库路径。

1.3.1  第一个jQuery程序(Hello World!)

在开始编写第一个jQuery程序之前,首先应该明确一点,在jQuery库中,$就是jQuery的一个简写形式,例如$(“#foo”)和jQuery(“#foo”)是等价的,如果没有特殊说明,程序中的$符号都是jQuery的一个简写形式。

第一个jQuery程序的主要代码如下:

      

运行结果如图1-1所示。

图1-1 输出Hello World

在上面的代码中有一个陌生的代码片段,如下:

$(document).ready(function(){

//…………

       });

这段代码的作用类似于传统JavaScript中的window.onload方法,不过与window.onload还是有些区别。表格1-1对它们进行了简单对比。

表1-1  window.onload与$(document).ready()的对比

 

Window.onload

$(document).ready();

执行时机

必须等待网页中所有内容加载完毕后(包含图片)才能执行

网页中所有DOM结构绘制完毕后就执行,可能DOM元素关联的东西并没有加载完

编写个数

不能同时编写多个以下代码无法正确执行:window.οnlοad=function(){

    alert("test1")

};

window.οnlοad=function(){

   alert("test2")

};

结果只会输出“test2”

能同时编写多个

以下代码正确执行

$(document).ready(function(){

         alert("Hello World!");

});

$(document).ready(function(){

         alert("Hello again!");

});

结果两次都输出

简化写法

$(document).ready(function(){

         …………….

})

简写成:

$( function(){

……………..

})

1.4 jQuery对象和DOM对象

1.4.1  DOM对象和jQuery对象简介

刚开始学习jQuery,经常分辨不清哪些是jQuery对象,哪些是DOM对象,因此需要重点了解jQuery对象和DOM对象以及它们之间的关系。

1.     DOM对象

DOM(Document ObjectModel,文档对象模型),每一份DOM都可以表示成一棵树。下面来构建一个基本的网页,网页代码如下:

 

初始化效果如图1-2所示。

可以把上面的HTML结构描述成一棵DOM树,如图1-3所示。


图1-2 基本网页运行结果

图1-3 网页元素可看成一棵树


在这棵DOM树中,<h3>、<p>、<ul>以及<ul>的3个<li>子节点都是DOM元素节点。可以通过JavaScript中的getElementByTagName或者getElementById来获取元素节点。像这样得到的DOM元素就是DOM对象。DOM对象可以使用JavaScript中的方法,

示例代码如下:

var domObj =document.getElementsById("id"); // Dom对象

var ObjHTML = domObj.innerHTML;  //使用JavaScript中的innerHTML方法

2.     jQuery对象

jQuery对象就是通过jQuery包装DOM对象后产生的对象。jQuery对象是jQuery独有的。如果一个对象是jQuery对象,那么就可以使用jQuery里的方法。例如:

$("#foo").html();//获取id为foo的元素内的html代码。

这段代码等同于:

document.getElementById("foo").innerHTML;

在jQuery对象中无法使用DOM对象的任何方法。例如$("#id").innerHTML和$("#id").checked之类的写法都是错误的,可以用$("#id").html()和$("#id").attr("checked")之类的jQuery方法代替。同样,DOM对象也不能使用jQuery里的方法,例如document.getElementById("id").html()也会报错,只能用document.getElementById("id").innerHTML语句。

1.4.2  jQuery对象和DOM对象的相互转换

在讨论jQuery对象和DOM对象的相互转换之前,先约定好定义变量的风格。如果获取的对象是jQuery对象,那么在变量前面加上$,例如:

var $variable = jQuery对象;

如果获取的是DOM对象,则定义如下:

var varible = DOM对象;

1.     jQuery对象转成DOM对象

jQuery对象不能使用DOM中的方法,但如果对jQuery对象所提供的方法不熟悉,或者jQuery没有封装想要的方法,不得不适用DOM对象的时候,有以下处理方法。

jQuery提供了两种方法将一个jQuery对象爱那个转换成DOM对象,即[index]和get(index).

(1)jQuery对象是一个数组对象,可以通过[index]的方法得到相应的DOM对象。jQuery代码如下:

var $cr = $("#cr");   //jQuery对象;

var cr = $cr[0];      //DOM对象;

alert(cr.checked);

(2)另一种方法是jQuery本身提供的,通过get(index)方法得到相应的DOM对象。jQuery代码如下:

var $cr=$("#cr");   //jQuery对象

var cr = $cr.get(0);  //DOM对象

alert(cr.checked);    //检测这个checkbox是否被选中了

2. DOM对象转换成jQuery对象

对于一个DOM对象,只需要用$()把DOM对象包装起来,就可以获得一个jQuery对象了。方式为 $(DOM对象)。

jQuery代码如下:

var cr=document.getElementById("cr");  //DOM对象

var $cr = $(cr);                         //jQuery对象

转换后,可以任意使用jQuery中的方法。

通过以上方法,可以任意地相互转换jQuery对象和DOM对象。

最后再次强调,DOM对象才能使用DOM中的方法,jQuery对象不可以使用DOM中的方法,但jQuery对象提供了一套更加完善的工具用于操作DOM,关于jQuery的DOM操作将在后面进行详细讲解。

注意:平时用到的jQuery对象都是通过$()函数制造出来的,$()函数就是一个jQuery对象的制造工厂。

1.4.3  实例研究

下面举个简单的例子,来加深对jQuery对象和DOM对象的理解。

有些论坛在用户注册的时候,必须先要同意论坛的规章制度,才可以进行下一步操作。

编写一段简单的代码来实现这个功能。新建一个空白页面,然后添加以下HTML代码:

<input type="checkbox"id="cr"/><label for="cr">我已经阅读了上面的制度。</label>

HTML代码初始效果如图1-4所示。

图1-4 初始效果

然后编写JavaScript部分。前面讲过,没有特殊声明,jQuery库是默认导入的。

通过$("#cr")获取到复选框元素,然后通过判断复选框是否被选中,来执行下一步操作。

首先,用DOM方式来判断复选框是否被选中,代码如下:

$(document).ready(function(){

      var$cr = $("#cr");  //jQuery对象

      varcr = $cr.get(0); //DOM对象,获取 $cr[0]

      $cr.click(function(){

             if(cr.checked){//DOM方式判断

                    alert("感谢你的支持!你可以继续操作!");

             }

      })

});

实现上述代码后,选中“我已经阅读了上面制度”复选框,如图1-5所示。

 

图1-5 选中选项后的效果图

换一种方式,使用jQuery中的方法来判断选项是否被选中,代码如下:

$(document).ready(function(){

      var$cr = $("#cr");  //jQuery对象

      $cr.click(function(){

             if($cr.is(":checked")){    //jQuery方式判断

                    alert("感谢你的支持!你可以继续操作!");

             }

      })

});

上面的例子简单地演示了DOM对象和jQuery对象的不同,但最终效果一样的。

二、  jQuery选择器

选择器是jQuery的根基,在jQuery中,对事件的处理、遍历DOM和Ajax操作都依赖于选择器。如果能熟练地使用选择器,不仅能简化代码,而且可以达到事半功倍的效果。

2.1 jQuery选择器是什么

jQuery中的选择器完全继承了css的风格。利用jQuery选择器,可以非常便捷和快速地找出特定的DOM元素,然后为他们添加相应的行为,而无需担心浏览器是否支持这一选择器。学会使用选择器是学习jQuery的基础,jQuery的行为规则都必须在获取到元素后才能生效。

下面来看一个简单的例子,代码如下:

<script type=”text/javascript”>

      Functiondemo(){

             Alert(“JavaScriptdemo.”);

}

</script>

<p οnclick=”demo();”>点击我</p>

本段代码的作用是为<p>元素设置一个onclick事件,当单击此元素时,会弹出一个对话框。

像上面这样把JavaScript代码和html代码混杂在一起的做法同样也非常不妥,因为它并没有将网页内容和行为分离,所以建议使用下面的方法,代码如下:

<p class=”demo”>jQuery Demo</p>

<script type=”text/javascript”>

$(“.demo”).click(function(){            //给class为demo的元素添加行为

Alert(“jQuery demo!”);

})

</script>

此时,可以对css的写法和jQuery的写法进行比较。

Css获取到元素的代码如下:

.demo{                                     //给class为demo的元素添加样式

      …….

}

jQuery获取到元素的代码如下:

$(“.demo”{                                              //给class为demo的元素添加行为

…………

jQuery选择器的写法与css选择器的写法十分类似,只不过两者的作用效果不同,css选择器找到元素后是添加样式,而jQuery选择器找到元素后是添加行为。需要特别说明的是,jQuery中涉及操作css样式部分比单纯的css功能更为强大,并且拥有跨浏览器的兼容性。

2.2 jQuery选择器的优势

1.   简洁的写法

$()函数在很多JavaScript类库中都被作为一个选择器函数来使用,在jQuery中也不例外。其中,$(“#ID”)用来代替document.getElementById()函数,即通过ID获取元素;$(“tagName”)用来代替document.getElementByTagName()函数,即通过标签名获取HTML元素。

2.支持css1到css3选择器

jQuery选择器支持css1,css2的全部和css3的部分选择器,同时他也有少量独有的选择器,因此对拥有一定css基础的开发人员来说,学习jQuery选择器是件非常容易的事,而对没有接触过css技术的开发人员来说,在学习jQuery选择器的同时也可以掌握css选择器的基本规则。

使用css选择器时,开发人员需要考虑是否支持某些选择器。而在jQuery中,开发人员则可以放心的使用jQuery选择器而无需考虑浏览器是否支持这些选择器。

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在这方面问题上的处理是非常不错的,即使用jQuery获取网页中不存在的元素也不会报错,看下面的例子,代码如下:

<div>test</div>

<script type=”text/javascript”>

$(“#tt”).css(“color”,”red”);   //这里无需判断$(“#tt”)是否存在

</script>

有了这个预防措施,即使以后因为某种原因删除网页上某个以前使用过的元素,也不用担心这个网页的JavaScript代码会报错。

需要注意的是,$(“#tt”)获取的永远是对象,即使网页上没有此元素。因此当要用jQuery检查某个元素在网页上是否存在时,不能使用以下代码:

If($(“#tt”)){

      //dosomething

}

而应该根据获取到元素的长度来判断,代码如下:

if($(“tt”).length>0){

      //dosomething

}

或者转换成DOM对象来判断,代码如下:

If($(“tt”)[0]){

      //dosomething

}

2.3 jQuery选择器

jQuery选择器分为基本选择器,层次选择器,过滤器选择器和表单选择器。在下面的章节中将分别用不同的选择器来查找HTML代码中的元素并对其进行简单的操作。为了能更清晰,直观的讲解选择器,首先需要设计一个简单的页面,里面包含各种<div>元素和<span>元素,然后使用jQuery选择器来匹配元素并调整他们的样式。

新建一个空白页面,输入以下html代码:

然后用CSS对这些元素进行初始化大小和背景颜色的设置,CSS代码如下:

根据以上HTML+CSS代码,可以生成图2-1所示的页面效果。

图2-1 初始状态

2.3.1  基本选择器

基本选择器是jQuery中最常用的选择器,也是最简单的选择器,它通过元素id、class和标签名等来查找DOM元素。在网页中,每个id名称只能使用一次,class允许重复使用。基本选择器的介绍说明如表2-1所示。

表2-1 基本选择器

选择器

描述

返回

示例

#id

根据给定的id匹配一个元素

单个元素

$(“#test”)选取id为test的元素

.class

根据给定的类名匹配元素

集合元素

$(“.test”)选取所有class为test的元素

element

根据给定的元素名匹配元素

集合元素

$(“p”)选取所有的<p>元素

*

匹配所有元素

集合元素

$(“*”)选取所有的元素

selector1, selector2,……, selectorN

将每一个选择器匹配到的元素合并后一起返回

集合元素

$(“div,span,p.myClass”)选取所有<div>,<span>和拥有class为myClass的<p>标签的一组元素

可以使用这些基本选择器来完成绝大多数的工作。下面用它们来匹配刚才HTML代码中的<div>,<span>等元素并进行操作(改变背景色),示例如表2-2所示。

表2-2 基本选择器示例

功能

代码

执行后

改变id为one的元素的背景色

$(“#one”).css(“background”,”#bbffaa”);

改变class为mini的所有元素的背景色

$(“.mini”).css(“background”,”#bbffaa”);

改变所有元素名是<div>的所有元素的背景色

$(“div”).css(“background”,”bbffaa”);

改变所有元素的背景色

$(“*”).css(“background”,”bbffaa”);

改变所有的<span>元素和id为two的元素的背景色

$(“span,#two”).css(“background”,”bbffaa”);

2.3.2  层次选择器

如果想通过DOM元素之间的层次关系来获取特定元素,例如后代元素、子元素、相邻元素和兄弟元素等,那么层次选择器是一个非常好的选择。层次选择器的介绍说明如表2-3所示。

表2-3 层次选择器

选择器

描述

返回

示例

$(“ancestor  descendant”)

选取ancestor元素里的所有descendant(后代元素)

集合元素

$(“div span”)选取<div>里的所有的<span>元素

$(“parent>child”)

选取parent元素下的child(子)元素

集合元素

$(“div > span”)选取<div>元素下元素名是<span>的子元素

$(“prev+next”)

选取紧接在prev元素后的next元素

集合元素

$(“.one+div”)选取class为one的下一个<div>元素

$(“prev~siblings”)

选取prev元素之后的所有siblings元素

集合元素

$(“#two~div”)选择id为two的元素后面的所有<div>兄弟元素

继续沿用刚才例子中的HTML和CSS代码,然后用层次选择器来对网页中的<div>,<span>等元素进行操作,示例如表2-4所示。

表2-4 层次选择器示例

功能

代码

执行后

改变<body>内所有<div>的背景色

$(“body div”).css(“background”,”#bbffaa”);

改变<body>内子<div>元素的背景色

$(“body>div”) .css(“background”,”#bbffaa”);

改变class为one的下一个<div>元素背景色

$(“.one+div”) .css(“background”,”#bbffaa”);

改变id为two的元素后面的所有<div>兄弟元素的背景色

$(“#two~div”) .css(“background”,”#bbffaa”);

在层次选择器中,第1个和第2个选择器比较常用,而后面两个因为在jQuery里可以用更加简单的方法代替,所以使用的几率相对少些。

可以用next()方法来代替$(“prev+next”)选择器,$(“.one+div”)就等价于$(“.one”).next(“div”)。可以用nextAll()方法来代替$(“prev~siblings”)选择器,$(“#prev~div”)就等价于$(“#prev”).nextAll(“div”)。

在此将siblings()方法与$(“prev~siblings”)选择器进行比较。

$(“#prev~div”)选择器只能选择”#prev”元素后面的同辈<div>元素。而siblings()方法与前后位置无关,只要是同辈元素节点就都能匹配。

$(“#prev~div”).css(“background”,”#bbffaa”);//选取#prev之后的所有同辈div元素

$(“#prev”).nextAll(“div”).css(“background”,”#bbffaa”);//同上

$(“#prev”).siblings(“div”).css(“background”,”#bbffaa”);//选取#prev所有的同辈div元素,无论前后位置

2.3.3  过滤选择器

过滤选择器主要是通过特定的过滤规则来筛选出所需的DOM元素,过滤规则与CSS的伪类选择器语法相同,即选择器都以一个冒号(:)开头。按照不同的过滤规则,过滤选择器可以分为基本过滤、内容过滤、可见性过滤、属性过滤、子元素过滤和表单对象属性过滤选择器。

1.     基本过滤选择器

表2-5 基本过滤选择器

选择器

描述

返回

示例

:first

选取第一个元素

单个元素

$(“div:first”)选取所有<div>元素中第一个<div>元素

:last

选取最后一个元素

单个元素

$(“div:last”)选取所有<div>元素中最后一个<div>元素

:not(selector)

去除所有与给定选择器匹配的元素

集合元素

$(“input:not(.myClass)”)选取class不是myClass的<input>元素

:even

选取索引是偶数的所有元素,索引从0开始

集合元素

$(“input:even”)选取索引是偶数的<input>元素

:odd

选取索引是奇数的所有元素,索引从0开始

集合元素

$(“input:odd”)选取索引是奇数的<input>元素

:eq(index)

选取索引等于index的元素(index从0开始)

单个元素

$(“input:eq(1)”)选取索引等于1的<input>元素

:gt(index)

选取索引大于index的元素(index从0开始)

集合元素

$(“input:gt(1)”)选取索引大于1的<input>元素(注:大于1,而不包括1)

:lt(index)

选取索引小于index的元素(index从0开始)

集合元素

$(“input:lt(1)”)选取索引小于1的<input>元素(注:小于1,而不包括1)

:header

选取所有的标题元素,例如h1,h2,h3等等

集合元素

$(“:header”)选取网页中所有的<h1>,<h2><h3>……

:animated

选取当前正在执行动画的所有元素

集合元素

$(“div:animated”)选取正在执行动画的<div>元素

接下来,使用这些基本过滤选择器来对网页中的<div>、<span>等元素进行操作,示例如表2-6所示。

表2-6 基本过滤选择器示例

功能

代码

执行后

改变第1个<div>元素的背景色

$(“div:first”).css(“background”,”#bbffaa”);

改变最后一个<div>元素的背景色

$(“div:last”).css(“background”,”#bbffaa”);

改变class不为one的<div>元素的背景色

$(“div:not(.one)”).css(“background”,”#bbffaa”);

改变索引值为偶数的<div>元素的背景色

$(“div:even”).css(“background”,”#bbffaa”);

改变索引为奇数的<div>元素的背景色

$(“div:odd”).css(“background”,”#bbffaa”);

改变索引等于3的<div>元素的背景色

$(“div:eq(3)”).css(“background”,”#bbffaa”);

改变索引值大于3的<div>元素的背景色

$(“div:gt(3)”).css(“background”,”#bbffaa”)

改变索引值小于3的<div>元素的背景色

$(“div:lt(3)”).css(“background”,”#bbffaa”);

改变所有的标题元素,例如:<h1>,<h2>.<h3>…这些元素的背景色

 $(“:header”).css(“background”,”#bbffaa”);

改变当前正在执行动画的元素的背景色

$("#mover").click(function(){  $(this).animate({"width":"+=100", "height": "+=100" }, "slow");        $(":animated").css("background", "#bbffaa");})

2.     内容过滤选择器

内容过滤选择器的过滤规则主要体现在它所包含的子元素或文本内容上。内容过滤选择器的介绍说明如表2-7所示。

         表2-7 内容过滤选择器

选择器

描述

返回

示例

:contains(text)

选取含有文本内容为text的元素

集合元素

$(“div:contains(‘我’)”)选取含有文本“我”的<div>元素

:empty

选取不包含子元素或者文本的空元素

集合元素

$(“div:empty”)选取不包含子元素(文本元素)的<div>空元素

:has(selector)

选取含有选择器所匹配的元素的元素

集合元素

$(“div:has(p)”)选取含有<p>元素的<div>元素

:parent

选取含有子元素或者文本的元素

集合元素

$(“div:parent”)选取拥有子元素(包含文本元素)的<div>元素

接下来使用内容过滤选择器来操作页面中的元素,示例如表2-8所示。

表2-8 内容过滤器示例

功能

代码

执行后

改变含有文本“di”的<div>元素的背景色    

$(‘div:contains(di)’).css(“background”,”#bbffaa”);

改变不包含子元素(文本元素)的<div>空元素的背景色

$(‘div:empty’) .css(“background”,”#bbffaa”);

改变含有class为mini元素的<div>元素的背景色    

$(‘div:has(.mini)’).css(“background”,”#bbffaa”);        

改变含有子元素(文本元素)的<div>元素的背景色

$(‘div:parent’) .css(“background”,”#bbffaa”);

3.     可见性过滤器

可见性过滤选择器是根据元素的可见和不可见状态来选择相应的元素。可见性过滤选择器的介绍说明如表2-9所示。

表2-9 可见性过滤选择器

选择器

描述

返回

示例

:hidden

选取所有不可见的元素

集合元素

$(“:hidden”)选取所有不可见的元素。包括<input type=”hidden”/>,<div style=”display:none;”>和<div style=”visibility:hidden;”>等元素。如果只想选取<input>元素,可以使用$(“input:hidden”)

:visible

选取所有可见的元素

集合元素

$(“div:visible”)选取所有可见的<div>元素

       在例子中使用这些选择器来操作DOM元素,示例如表2-10所示。

表2-10 可见性过滤选择器示例

功能

代码

执行后

改变所有可见的<div>元素的背景色

$(“div:visible”).css(“background” ,”#FF6500”)        

显示隐藏的<div>元素

$(“div:hidden”) .show(3000);

在可见性选择器中,需要注意选择器:hidden,它不仅包括样式属性display为“none”的元素,也包括文本隐藏域(<input type=”hidden”/>)和visibility:hidden之类的元素。

4.     属性过滤选择器

属性过滤选择器的过滤规则是通过元素的属性来获取相应的元素。属性过滤选择器的介绍说明如表2-11所示。

表2-11 属性过滤选择器

选择器

描述

返回

示例

[attribute]

选取拥有此属性的元素

集合元素

$(“div[id]”)选取拥有属性id的元素

[attribute=value]

选取属性的值为value的元素

集合元素

$(“div[title=test]”)选取属性title为“test”的<div>元素

[attribute!=value]

选取属性的值不等于value的元素

集合元素

$("div[title!=test]”)选取属性title不等于“test”的<div>元素(注意:没有属性title的<div>元素也会被选取)

[attribute^ =value]

选取属性的值以value开始的元素

集合元素

$("div[title^=test]")选取属性title以“test”开始的<div>元素

[attribule$=value]

选取属性的值以value结束的元素

集合元素

$("div[title$=test]“)选取属性title以“test”结束的<div>元素

[attribute*=value]

选取属性的值含有value的元素

集合元素

$(“div[title*=test]”)选取属性title含有“test”的<div>元素

[selectorl][selectm2][selectorN]

用属性选择器合并成一个复合属性选择器,满足多个条件。每选择一次,缩小一次范围

集合元素

$(“div[id] [title$=’test’]”)选取拥有属性id,并且属性title以”test”结束的<div>元素

接下来使用属性过滤器来对<div>和<span>等元素进行操作,示例如表2-12所示。

表2-12 属性过滤选择器示例

功能

代码

执行后

改变含有属性title的 <div>元素的背景色

$(‘div[title]’).css("background","#bbffaar);

改变属性title值等于“test”的<divsssss>元素的背景色        

$(‘div[title=test]’).css(“background”,”#bbffaa”);

改变属性title值不等于“test”的<div>元素的背景色

$(‘div[title!=test]’).css(“background”,” #bbffaa”);

改变属性title值以“te”开始的<div>元素的背景色

$(“div[title^=te]”).css(“background”,” #bbffaa”);

改变属性title值以“est”结束的<div>元素的背景色

$(“div[title$=est]”) .css(“background”,” #bbffaa”);

改变属性title值含有“es”的<div>元素的背景色

$(“div[title*=es]”).css(“background”, “#bbffaa”);

改变含有属性id,并且属性title值含有”es”的<div>元素的背景色

$(“div[id][title*=es]”) .css(“background”,” #bbffaa”);

5.     子元素过滤选择器

子元素过滤选择器的过滤规则相对于其他的选择器稍微有些复杂,不过没关系,只要将元素的父元素和子元素区分清楚,那么使用起来也非常简单。另外还要注意它与普通的过滤选择器的区别。

子元素过滤选择器的介绍说明如表2-13所示。

表2-13 子元素过滤选择器

选择器

描述

返回

示例

:nth-child(index/even/odd/equation)

选择每个父元素下的第index个子元素或者奇偶元素(indes从1算起)

集合元素

:eq(index)只匹配一个元素,而:nth-child将为每一个父元素匹配子元素,并且:nth-child(index)的index是从1开始的,而:eq(index)是从0算起的

:first-child

选取每个父元素的第1个元素

集合元素

:first只返回单个元素,:first-child选择副符将为每个父元素匹配第1个子元素。例如$(“ul li:first-child”);选取每个<ul>中第1个<li>元素

:last-child

选取每个父元素的最后个元素

集合元素

同样,:last只返回单个元素,而:last-child选择符将为每个父元素匹配最后一个子元素 例如$(“ul li:last-child”);选择每个<ul>最后一个<li>元素

:only-child

如果某个元素是它父元素的唯一的子元素,那么将会被匹配。如果父元素中含有其它元素,则不会被匹配

集合元素

$(“ul li:only-child”)在<ul>中选取是唯一子元素的<li>元素

:nth-child()选择器是很用的子元素过滤选择器,详细功能如下。

(1):nth-child(even)能选取每个父元素下的索引值是偶数的元素。

(2):nth-child(odd) 能选取每个父元素下的索引值是奇数的元素。

(3):nth-child(2)能选取每个父元素下的索引值等于2的元素。

(4):nth-child(3n) 能选取每个父元素下的索引值是3的倍数的元素,(n从0开始)。

(5):nth-child(3n+1) 能选取每个父元素下的索引值是(3+1)的元素。(n从0开始)

接下来利用刚才所讲的选择器来改变<div>元素的背景色,示例如表2-14所示。

表2-14 子元素过滤选择器示例

功能

代码

执行后

改变每个class为one的<div>父元素下的第2个子元素的背景色

$(“div.one  :nth-child(2)”) .css(“background”,”#bbffaa”);

改变每个class为One的 <div>父元素下的第1个子元素的背景色

$(“div.one :first-child).css(“background”,”#bbffaa”);

改变每个class为One的 <div>父元素下的最后一个子元素的背景色

$(“div.one :last-child“).css(“background”,”#bbffaa”);

改变每个class为One的 <div>父元素下只有一个子元素,那么则改变这个子元素的背景色

$(“div.one :only-child”).css(“background”,”#bbffaa”);

6.     表单对象属性过滤选择器

此选择器主要是对所选择的表单元素进行过滤,例如选择被选中的下拉框,多选框等等。表单对象属性过滤选择器的介绍说明如表2-15所示。

表2-15 表单对象属性过滤选择器

选择器

描述

返回

示例

:enabled

选取所有可用元素

集合元素

$(“#forml  :enabled”);选取id为“forml”的表单内的所有可用元素

:disabled

选取所有不可用元素

集合元素

$(“#form2  :disabled”)选取id为“form2” 的表单内的所有不可用元素

:checked

选取所有被选中的元素(单选框,复选框)   

集合元素

$(“input:checked”);选取所有被选中的<input>元素

:selected

选取所有被选中的选项元素(下拉列表)

集合元素

$(“select :selected”);选取所有被选中的选项元素

为了演示这些选择器,需要制作一个包含表单的网页,里面要包含文本框、多选框和下拉列表,HTML代码如下:

<form id="form1"action="#">

      <buttontype="reset">重置所有表单元素</button>

      <br/><br />

 <button id="btn1">对表单内 可用input 赋值操作.</button>

 <button id="btn2">对表单内 不可用input 赋值操作.</button><br/><br />

     

     可用元素:<input name="add" value="可用文本框"/>  <br/>

     不可用元素:<input name="email" disabled="disabled"value="不可用文本框"/><br/>

     可用元素: <input name="che" value="可用文本框" /><br/>

       不可用元素:<inputname="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>

             <optionselected="selected">湖南</option>

             <option>北京</option>

             <optionselected="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>

生成的效果图如图2-2所示。

图2-2 初始状态

现在用jQuery的表单过滤选择器来操作它们,示例如表2-16所示。

表2-16 表单对象属性过滤示例

功能

代码

执行后

改变表单内可用<input>元素的值

$(”#forml input:enabled").val(”这里变化了!”);

改变表单内不可用<input>元素的值

$ ("#forml  input:disabled").val(”这里变化了!”);

获取多选框选中的个数

$ ("input:checked") .length;

获取下拉框选中的内容

$ ("select :selected") .text () ;

2.3.4  表单选择器

为了使用户能够更加灵活地操作表单,jQuery中专门加入了表单选择器,能极其方便地获取到表单的某个或某类型的元素。

表单选择器的介绍说明如表2-17所示。

表2-17 表单对象属性过滤示例

选择器

描述

返回

示例

:input

选取所的<input>、<textarea>、<select>和<button>元素

集合元素

$(“:input”)选取所有<input>、<textarea>、<select>和<button>元素

:text

选取所有的单行文本框

集合元素

$(“:text”)选取所有的单行文本框

:password

选取所有的密码框

集合元素

$(“:password”)选取所有的密码框

:radlO

选取所有的单选框

集合元素

$(“:radio”)选取所有的单选框

:checkbox

选取所有的多选框

集合元素

$(“:checkbox”)选取所有的复选框

:submit

选取所有的提交按钮

集合元素

$(“:submit”)选取所有的提交按

:image

选取所有的图像按钮

集合元素

$(”:image”)选取所有的图像按钮

:reset

选取所有的重置按钮

集合元素

$(“:reset”)选取所有的重置按钮

:button

选取所有的按钮

集合元素

$(“:button”)选取所有的按钮

:file  

选取所有的上传域

集合元素

$(“:file”)选取所有的上传域

:hidden

选取所有不可见元素

集合元素

$(“:hidden”)选取所有不可见元素(已经在不可见性过滤选择器中讲解过)

下面把这些表单选择器运用到下面的表单中,对表单进行操作。

表单HTML代码如下:

<form id="form1"action="#">

   <input type="button"value="Button"/><br/>

   <input type="checkbox" name="c"/>1<inputtype="checkbox" name="c"/>2<inputtype="checkbox" name="c"/>3<br/>

   <input type="file" /><br/>

    <input type="hidden" /><divstyle="display:none">test</div><br/>

   <input type="image" /><br/>

   <input type="password" /><br/>

   <input type="radio" name="a"/>1<inputtype="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 rows="5"cols="20"></textarea><br/>

   <button>Button</button><br/>

 </form>

根据以上HTML代码,可以生成图2-3所示的页面效果。

图2-3 初始状态

如果想得到表单内表单元素的个数,代码如下:

$(“#form1 :input”).length;     //注意与$(“#form1 input”)的区别

如果想得到表单内单行文本框的个数,代码如下:

$(“#form1 :text”).length;

如果想得到表单内密码框的个数,代码如下:

$(“#form1 :password”).length;

同理,其他表单选择器的操作与此类似。

2.4选择器中的一些注意事项

2.4.1  选择器中含有特殊符号的注意事项

1.选择器中含有“.”、“#”、“(”或“]”等特殊字符

2.根据W3C的规定,属性值中是不能含有这些特殊字符的,但在实际项目中偶尔会遇到表达式中含有“#”和“.”等特殊字符,如果按照普通的方式去处理出来的话就会出错。解决此类错误的方法是使用转义符转义。

HTML代码如下:

<div id=”id#b”>bb</div>

<div id=”id[1]”>c</div>

如果按照普通的方式来获取,例如:

$(‘#id#b’);

$(‘#id’[1]);

以上代码不能正确获取元素,正确的写法如下:

$(‘#id\\#b’);                      //转义特殊字符“#”

$(‘#id\\[1\\]’);                    //转义特殊字符“[  ]”

2.4.2  选择器中含有空格的注意事项

选择器中的空格也是不容忽视的,多一个空格或少一个空格也许会得到截然不同的结果。

看下面的例子,它的HTML代码如下:

<body>

      <divclass="test">

         <divstyle="display:none;">aa</div>

         <divstyle="display:none;">bb</div>

         <div style="display:none;">cc</div>

         <div class="test"style="display:none;">dd</div>

      </div>

      <divclass="test" style="display:none;">ee</div>

      <divclass="test" style="display:none;">ff</div>

</body>

使用如下的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.5 案例研究——某网站品牌列表的效果

实现某网站上的一个品牌列表的展示效果,用户进入该页面时,品牌列表默认是精简显示的(即不完整的品牌列表)。

用户可以单击“显示全部品牌”按钮来显示全部的品牌。

单击“显示全部品牌”按钮的同时,列表会将推荐的品牌的名字高亮显示,按钮里的文字也换成了“精简显示品牌”。

为了实现这个例子,首先需要设计它的HTML结构。HTML代码如下:

<divclass="SubCategoryBox">

<ul>

<li ><ahref="#">佳能</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>

      <divclass="showmore">

             <ahref="more.html"><span>显示全部品牌</span></a>

      </div>

</div>

然后为上面的HTML代码添加CSS样式。

页面初始化的效果如图2-4所示。

图2-4 品牌展示列表(精简)

接下来为这个页面添加一些交互效果,

要做的工作有以下几项。

(1) 从第7条开始隐藏后面的品牌(最后一条“其它品牌相机”除外)。

(2) 当用户单击“显示全部品牌”按钮时,将执行以下操作。

①  显示隐藏的品牌。

②“显示全部品牌”按钮文本切换成“精简显示品牌”。

③ 高亮推荐品牌。

(3) 当用户单击“精简显示品牌”按钮时,将执行以下操作。

①从第5条开始隐藏后面的品牌(最后一条“其它品牌相机”除外)。

②“精简显示品牌”按钮文本切换成“显示全部品牌”。

③去掉高亮显示的推荐品牌。

(4) 循环进行第(2)步和第(3)步。

下面逐步来完成以上的效果。

(1)  从第5条开始隐藏后面的品牌(最后一条“其他品牌相机”除外)。

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');     //获取“显示全部品牌”按钮

然后给按钮添加事件,使用show()方法把隐藏的品牌列表显示出来,代码如下:

$toggleBtn.click(function(){

                $category.show();                  //添加高亮样式

                return false;               //超链接不跳转

         });

由于给超链接添加onclick事件,因此需要使用“return false”语句让浏览器认为用户没有单击该超链接,从而阻止该超链接跳转。

之后,需要将“显示全部品牌”按钮文本切换成“精简显示品牌”,代码如下:

$('.showmore a span')

                    .css("background","url(img/up.gif)no-repeat 0  0")

                    .text("精简显示品牌");              //这里使用了连接操作

这里完成了两步操作,即把按钮的背景图片换成向上的图片,同时也改变了按钮文本内容,将其替换成“精简显示品牌”。

接下来需要高亮推荐品牌,代码如下:

$('ul li').filter(":contains('佳能'),:contains('尼康'),:contains('奥林巴斯')")

                .addClass(“promoted”)     //添加高亮样式

使用filter()方法筛选出符合要求的品牌,然后为它们添加promoted样式。在这里推荐了3个品牌,即佳能、尼康和奥林巴斯。

此时,完成的iQuery代码如下:

$(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

                    $('.showmorea span')

                           .css("background","url(img/up.gif)no-repeat 0 0")     

                           .text("精简显示品牌");      //改变背景图片和文本

             $('ulli').filter(":contains('佳能'),:contains('尼康'),:contains('奥林巴斯')")

                           .addClass("promoted");                         //添加高亮样式

                    returnfalse;                                //超链接不跳转

             })

})

运行上面的代码,单击“显示全部品牌”按钮后,显示图2-5所示的效果,此时已经能够正常显示全部品牌了。

 

图2-5 当按钮被单击后

(3)  当用户单击“精简显示品牌”按钮时,将执行以下操作。

由于用户单击的是同一个按钮,因此事件仍然是在刚才的按钮元素上。要将切换两种状态的效果在一个按钮上进行,可以通过判断元素的显示或者隐藏来达到目的,代码结构如下:

if(元素显示)){

  //元素隐藏①

}else{

  //元素显示②

}

代码②就是第(2)步的内容,接下来只需要完成代码①的内容即可。

在jQuery中,与show()方法相反的是hide()方法,因此可以使用hide()方法将品牌隐藏起来,代码如下:

$category.hide();                                //  隐藏$category

然后将“精简显示品牌”按钮文本切换成“显示全部品牌”,同时按钮图片换成向下的图片,这一步与前面类似,只不过是图片路径和文本内容不同而已,代码如下:

$('.showmore a span')

             .css("background","url(img/up.gif)no-repeat 0 0")

             .text("精简显示品牌");                  //改变背景图片和文本

接下来需要去掉所有品牌的高亮显示状态,此时可以使用removeClass()方法来完成,代码如下:

$('ulli').removeClass("promoted");                   //去掉高亮样式

它将去掉所有<li>元素上的“promoted”样式,即去掉了品牌的高亮状态。

至此完成代码①。

最后通过判断元素是否显示来分别执行代码①和代码②,代码如下:

     if($category判断.is(":visible")){     //如果元素显示,则执行对应的代码

之后即可将代码①和代码②插入相应的位置。jQuery代码如下:

if($category.is(":visible")){                        //如果元素显示

             $category.hide();                   // 隐藏$category

             $('.showmore a span')

                    .css("background","url(img/down.gif)no-repeat 0 0")

                    .text("显示全部品牌");         //改变背景图片和文本

             $('ulli').removeClass("promoted");      //去掉高亮样式

 }else{

      $category.show();                      //  显示$category

      $('.showmorea span')

             .css("background","url(img/up.gif)no-repeat 0 0")

             .text("精简显示品牌");            //改变背景图片和文本

      $('ulli').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(){

                   if($category.is(":visible")){

                                  $category.hide();          // 隐藏$category

                                  $('.showmorea span')

                                         .css("background","url(img/down.gif)no-repeat 0 0")     

                                         .text("显示全部品牌");   //改变背景图片和文本

                                  $('ulli').removeClass("promoted");// 去掉高亮样式

                     }else{

                                  $category.show();       // 显示$category

                                  $('.showmorea span')

                                         .css("background","url(img/up.gif)no-repeat 0 0")     

                                         .text("精简显示品牌");  //改变背景图片和文本

                                  $('ulli').filter(":contains('佳能'),:contains('尼康'),:contains('奥林巴斯')") .addClass("promoted");                          //添加高亮样式

                           }

                    returnfalse;                                     //超链接不跳转

             })

})

运行代码后,单击按钮,品牌列表会在“全部”和“精简”两种效果之间循环切换,显示效果如图2-6和图2-7所示。

图2-6 精简模式

图2-7 全部模式

在jQuery中有一个方法更适合上面的情况,它能给一个按钮添加一组交互事件,而不需要像上例一样去判断,上例的代码如下:

 toggleBtn.click(function(){

      if($category.is(“:visible”)){            //如果元素显示

//元素隐藏  ①

}else{

             //元素显示  ②

}

})

如果改成toggle()方法,代码则可以直接写成以下形式:

$toggleBtn. toggle (function(){            //toggle()方法用来交换一组动作

      if($category.is(“:visible”)){          //如果元素显示

//元素隐藏①

},toggle(){

             //元素显示②

}

})

当单击按钮后,脚本会对代码③和代码④进行交替处理。

三、  jQuery中的DOM操作

DOM是Document Object Model的编写JavaScript,意思是文档对象的模型。根据w3c DOM规范,DOM是一种与浏览器、平台、语言无关的接口,使用该接口可以轻松的访问页面中的所有的标准组件。简单来说,DOM解决了Netscape的Javascript和Microsoft的Jscript之间的冲突,给予了Web设计师和开发者一套便准的方法,让他们能够轻松获取和操作网页中的数据、脚本和表现层对象。

3.1 DOM操作的分类

一般来说,DAM操作分为3个方面,即DOMCore(核心)、HTML-DOM和CSS-DOM。

1.   DOM Core

DOM Core并不专属于JavaScript,任何一种支持dom的程序设计语言都可以使用。他的用途并非仅限于处理网页,也可以用来处理任何一种使用标记语言编写出来的文档,例如XML。

JavaScript中的getElementById()、getElementByTagName()和setAttribute()等方法,这些都是DOM Core的组成部分。

例如:

使用DOM Core来获取表单对象的方法:

document.getElementsByTagName(“form”);

使用DOM Core来获取某元素的src的属性的方法 :

element.getAttribute(“src”);

2.HTML_DOM

在使用JavaScript和DOM为HTML文件编写脚本时,有许多专属于HTML-DOM的属性。HTML-DOM的出现甚至比DOM Core还要早,他提供了一些更简明的记号来描述各种HTML元素的属性。

例如:

使用HTML-DOM来获取表单对象的方法:

document.forms;  // HTML-DOM提供了一个forms对象

使用HTML-DOM来获取某元素的src属性的方法:

element.src;

通过上面所说的方法,可以发现获取某些对象、属性既可以用DOM  Core来实现也可以使用HTML-DOM来实现。相比较而言HTML-DOM的代码通常比较简单,不过他只能用来处理WEB文档。

3.CSS_DOM

CSS_DOM 是针对CSS的操作。在JAVASCRIPT中,CSS-DOM技术的主要作用是获取和设置style对象的各种属性。通过改变style对象的各种属性,可以使网页呈现出各种不同的效果。

例如:设置某元素style对象字体颜色的方法

Element.style.color=“red”;

jQuery作为javascript库,继承并发扬了javascript对DOM对象的操作的特性,使开发人员能方便的操作DOM对象。下面详细介绍jQuery中的各种DOM操作。

3.2 jQuery中的DOM操作

为了能全面讲解DOM操作,首先需要构建一个网页。因为每一张网页都能用DOM表示出来,而一份DOM都可以看作一棵DOM树。构建的网页如图3-1所示。

HTML代码如下:

<head>

<meta http-equiv="Content-Type"content="text/html; charset=utf-8" />

<title>dom</title>

</head>

<body>

      <ptitle="选择你最喜欢的水果." >你最喜欢的水果是?</p>

<ul>

        <li title='苹果'>苹果</li>

        <li title='橘子'>橘子</li>

        <li title='菠萝'>菠萝</li>

      </ul>

</body>

       根据上面的网页结构构建出一棵DOM树,如图3-2所示。


图3-1 网页效果

图3-2 DOM结构


接下来,对DOM的各种操作都将围绕这棵DOM树而展开。

3.2.1  查找节点

使用jQuery在文档树上查找节点非常容易,可以通过在第二章介绍的jQuery选择器来完成。

1.     查找元素节点

获取元素节点并打印出它的文本内容,jQuery代码如下:

var $li = $("ul li:eq(1)");   // 获取第二个<li>元素节点

var li_txt = $li.text(); // 输出第二个<li>元素节点的text

alert(li_txt);

以上代码获取了<ul>元素里的第2个<li>节点,并将它的文本内容“橘子“打印出来。

2.   查找属性节点

利用jQuery选择器查找到需要的元素后,就可以使用attr()方法来获取它的各种属性的值。Attr()方法的参数可以是一个,也可以是两个。当参数是一个时,则是要查询的属性的名字,例如:

获取属性节点并打印出它的文本内容,jquery代码如下:

var $para = $("p");                  // 获取<p>节点

var p_txt = $para.attr("title");// 输出<p>元素节点属性title

alert(p_txt);                      //打印title属性值

以上代码获取了<p>节点,并将它的title属性的值打印出来。

3.2.2  创建节点

利用jQuery选择器能够快捷而轻松地查找到文档中的某个特定的元素节点,然后可以用attr()方法来获取元素的各种属性的值。

真正的DOM操作并非这么简单。在DOM操作中,常常需要动态创建HTML内容,使文档在浏览器里的呈现效果发生变化,并且达到各种各样的人机交互的目的。

1.     创建元素节点

例如要创建两个<li>元素节点,并且要把他们作为<ul>元素节点的子节点添加到DOM节点树上,完成这个任务需要两个步骤。

(1)   创建两个<li>新元素。

(2)   将这两个新元素插入文档中。

第(1)个步骤可以使用jQuery的工厂函数$()来完成,格式如下:

$( html );

$( html )方法会根据传入的HTML标记字符串,创建一个DOM对象后返回。

首先创建两个<li>元素,jQuery代码如下:

var $li_1 =$("<li></li>");   //  创建第一个<li>元素

var $li_2 =$("<li></li>");   //  创建第二个<li>元素

然后将这两个新元素插入文档中,可以使用jQuery中的append()等方法(将在3.2.3小结进行介绍)。

jQuery代码如下:

$(“ul”).append($li_1);

$(“ul”).append($li_2);         // 添加到<ul>节点中,使之能在网页中显示

运行代码后,新创建的<li>元素将被添加到网页中,因为暂时没有在它们内部添加任何文本,所以只能看到<li>元素、默认的”·”,如图3-3所示。

2.     创建文本节点

已经创建了两个<li>元素节点并把它们插入文档中了。此时需要为创建的元素节点添加文本内容。

jQuery代码如下:

var $li_1 = $("<li>香蕉</li>");       // 创建一个<li>元素,包括元素节点和文本节点

                                                       //“香蕉”就是创建的文本节点。

var $li_2 = $("<li>雪梨</li>");       // 创建一个<li>元素,包括元素节点和文本节点

                                                       //“雪梨”就是创建的文本节点。

$("ul").append($li_1);         // 添加到<ul>节点中,使之能在网页中显示

$("ul").append($li_2);         // 添加到<ul>节点中,使之能在网页中显示

如以上代码所示,创建文本节点就是创建元素节点时直接把文本内容写出来,然后使用append()等方法将它们添加到文档中就可以了。

创建的<li>节点显示到网页中的效果如图3-4所示。

3.   创建属性节点

创建属性节点与创建文本节点类似,也是直接在创建元素节点时一起创建。

jQuery代码如下:

var $li_1 = $("<li  title=’香蕉’ >香蕉</li>");    //创建一个<li>元素,包括元素节点,文本节点,属性节点

                                                       //其中title=‘香蕉’就是创建的属性节点。

var $li_2 = $("<li  title=’雪梨’>雪梨</li>");     //创建一个<li>元素,包括元素节点和文本节点,属性节点

                                                       //“雪梨”就是创建的属性节点。

$("ul").append($li_1);         // 添加到<ul>节点中,使之能在网页中显示

$("ul").append($li_2);

运行代码后,效果如图3-5所示。


图3-3 创建元素节点

图3-4 创建文本节点

图3-5 创建属性节点


由此可见用jQuery来动态创建HTML元素是非常简单,方便和灵活的。

3.2.3  插入节点

动态创建HTML元素并没有实际用处还需要将新创建的元素插入文档中。将新创建的节点插入文档最简单的办法是,让它成为这个文档的某个节点的子节点。前面使用了一个插入节点的方法append(),它会在元素内部追加新创建的内容。

将新创建的节点插入某个文档的方法并非只有一种,在jQuery中海提供了其他几种插入节点的方法,如表3-1所示。读者可以根据实际需求灵活的坐出多种选择。

表3-1 插入节点的方法

方法

描述

示例

Append()          

向每个匹配的元素内部追加内容

HTML代码:

<p>我想说:</p>

jQuery代码:

$(“p”).append(“<b>你好</b>”)

结果:

<p>我想说:<b>你好</b></p>

appendTo()

将所有匹配的元素追加到指定的元素中。实际上,使用该方法是颠倒了常规的$(A).append(b)的操作,即不是将B追加到A中,而是将A追加到B中

HTML代码:

<p>我想说:</p>

jQuery代码:

$(“<b>你好</b>”).appendTo(“P”)

结果:

<p>我想说:<b>你好:</b></p>

Prepend()

向每个匹配的元素内部前至内容

HTML代码:

<p>我想说:</p>

jQuery代码:

$("p").prepend("<b>你好</b>")

结果:

<p><b>你好</b>我想说: </p>

PrependTo()

将所有匹配的元素前置到指定的元素中。实际上,使用该方法是颠倒了常规的$(A).prepend(B)的操作,即不是将B前置到A中,而是将A前置到B中

HTML代码:

<p>我想说:</p>

jQuery代码:

$("<b>你好</b>").prependTo("p")

结果:

<p><b>你好</b>我想说: </p>

after()

在每个匹配的元素之后插入内容

HTML代码:

<p>我想说:</p>

jQuery代码:

$(“p”). after (“<b>你好</b>”)

结果:

<p>我想说: </p><b>你好</b>

insertAfter()

将所有匹配的元素插入到指定的元素中。实际上,使用该方法是颠倒了常规的$(A).after(b)的操作,即不是将B插入到A中,而是将A插入到B中

HTML代码:

<p>我想说:</p>

jQuery代码:

$(“<b>你好</b>”). insertAfter (“P”)

结果:

<b>你好:</b><p>我想说: </p>

before()

在每个匹配的元素之前插入内容

HTML代码:

<p>我想说:</p>

jQuery代码:

$("p"). before ("<b>你好</b>")

结果:

<b>你好</b><p>我想说: </p>

insertBefore()

将所有匹配的元素插入到指定的元素中。实际上,使用该方法是颠倒了常规$(A).before(B)的操作,即不是将B插入到A中,而是将A插入到B中

HTML代码:

<p>我想说:</p>                                                                       

jQuery代码:

$("<b>你好</b>"). insertBefore ("p")

结果:

<p>我想说: </p><b>你好</b>

这些插入节点的方法不仅能将新创建的DOM元素插入到文档中,也能对原有的DOM元素进行移动。

例如利用他们创建新元素并对其进行插入操作。

jQuery代码如下:

var $li_1 = $("<li title='香蕉'>香蕉</li>"); //创建第1个<li>元素

var $li_2 =$("<li title='雪梨'>雪梨</li>");  //创建第2个<li>元素

var $li_3=$("<li title='其他'>其他</li>");   //创建第3个<li>元素

var $parent = $("ul");              // 获取<ul>节点,即<li>的父节点

var $two_li = $("ul li:eq(1)");//  获取<ul>节点中第二个<li>元素节点

$parent.append($li_1);    // append方法将创建的第一个<li>元素添加到父元素的最后面

$parent.prepend($li_2);  // prepend方法将创建的第二个<li>元素添加到父元素里的最前面

$li_3.insertAfter($two_li); //  insertAfter方法将创建的第三个<li>元素元素插入到获取的<li>之后

运行代码后,网页呈现效果如图3-6所示。

图3-6 插入节点

例如利用他们对原有的DOM元素进行移动。

jQuery代码如下:

var $one_li = $("ul li:eq(1)");                      //  获取<ul>节点中第二个<li>元素节点

var $two_li = $("ul li:eq(2)");                      //  获取<ul>节点中第三个<li>元素节点

$two_li.insertBefore($one_li);       //   移动节点


图3-7 移动之前

图3-8 移动之后


3.2.4  删除节点

如果文档中某一个元素多余,那么应将其删除。jQuery提供了两种删除节点的方法,即remove()和empty()。

1.   remove()方法

作用是从DOM中删除所有匹配的元素,传入的参数用于根据jQuery表达式来筛选元素。

例如删除图3-7中<ul>节点中的第二个<li>元素节点,jQuery代码如下:

$("ul li:eq(1)").remove(); // 获取第二个<li>元素节点后,将它从网页中删除。

运行代码后效果如图3-9所示。

图3-9 删除节点

当某个节点用remove()方法删除后,该节点所包含的所有后代节点将同时被删除。这个方法的返回值是一个指向已被删除的节点的应用,因此可以在以后在使用这些元素。下面的jQuery代码说明元素用remove()方法删除后,还是可以继续使用的。

var $li = $("ulli:eq(1)").remove(); // 获取第二个<li>元素节点后,将它从网页中删除。

$li.appendTo("ul");         // 把刚才删除的又重新添加到<ul>元素里

可以直接使用appendTo()方法的特性来简化以上代码,jQuery代码如下:

$("ulli:eq(1)").appendTo(“ul”);//appendTo()方法也可以用来移动元素

//移动元素是首先从文档上删除此元素,然后将该元素插入得到文档中的指定的节点。         

另外remove()方法也可以通过传递参数来选择性的删除元素,jQuery代码如下:

$("ul li").remove(“li[title!=菠萝]”);

                           //将<li>元素中的属性title不等于“菠萝”的<li>元素删除

运行代码后,效果如图3-10所示。

图3-10 有选择性的删除文件

2.   empty()方法

严格来讲,empty()方法并不是删除节点,而是清空节点,它能清空元素中的所有后代节点。

$("ul li:eq(1)").empty();//获取第2个元素节点后;清空此元素里的内容,注意是元素里。

当运行代码后,第2个<li>元素的内容被清空了,只剩下<li>标签的默认的符号”·”,效果如图3-11所示。

图3-11 清空元素

3.2.5  复制节点

复制节点也是常用的DOM操作之一。继续沿用之前的例子,如果单击<li>元素后需要在复制一个<li>元素,可以使用clone()方法来完成,jQuery代码如下:

$("ul li").click(function(){

$(this).clone().appendTo("ul");//复制当前点击的节点,并将它追加到<ul>元素

});

在页面中单击“橘子”后,列表最下方出现新节点“橘子”,效果如图3-12所示:

图3-12 复制节点

复制节点后,被复制的新元素并不具有任何行为。如果需要新元素也具有复制功能(本例中是单击事件),可以使用如下jQuery代码:

$(this).clone(true).appendTo("body");// 注意参数true

在clone()方法中传递了一个参数true,它的含义是复制元素的同时复制元素所绑定的事件。因此该元素的副本也同样具有复制功能(本例中是单击事件)。

3.2.6  替换节点

如果要替换某个节点,jQuery提供了相应的方法,即replaceWith()和replaceAll()。

ReplaceWith()方法的作用是将所有匹配的元素都替换成指定的html或者DOM元素。

例如要将网页中”<p title=“选择你最喜欢的水果”>你最喜欢的水果是?</p>”替换成”<strong>你最不喜欢的水果是?</strong>”,可以使用如下jQuery代码:

$(“p”).replaceWith(“<strong>你最不喜欢的水果是?</strong>”);

也可以使用jQuery中另一个方法replaceAll()来实现,该方法与replaceWith()方法的作用相同,只是颠倒了replaceWith()操作,可以使用如下jQuery代码实现同样的功能:

$("<strong>你最不喜欢的水果是?</strong>").replaceAll("p");

这两句jQuery代码都会实现图3-13所示的效果。

图3-13 替换节点

如果在替换之前,已经为元素绑定事件,替换后原先绑定的事件将会与被替换的元素一起消失,需要在新元素上重新绑定事件。

3.2.7  包裹节点

如果要将某个节点用其他标记包裹起来,jQuery提供了相应的方法,即wrap()。该方法对于需要在文档中插入额外的结构化标记非常有用,而且他不会破坏原始文档的语义。

jQuery代码如下:

$("strong").wrap("<b></b>");//用<b>元素把<strong>元素包裹起来

得到的结果如下:

<b><strong title=”选择你最喜欢的水果。”>你最喜欢的水果是?</strong></b>

包裹节点操作还有其他两个方法,即wrapAll()和wrapInner()。

1.wrapAll()方法

该方法会将所有匹配的元素用一个元素来包裹。他不同于wrap()方法,wrap()方法是将所有的元素进行单独的包裹。

为了使效果更突出,在网页中在加入一个<strong>元素。

HTML代码如下:

      <strongtitle="选择你最喜欢的水果." >你最喜欢的水果是?</strong>

      <strongtitle="选择你最喜欢的水果." >你最喜欢的水果是?</strong>

      <ul>

        <li title='苹果'>苹果</li>

        <li title='橘子'>橘子</li>

        <li title='菠萝'>菠萝</li>

      </ul>

如果使用wrap()方法包裹<strong>元素,jQuery代码如下:

$("strong").wrap("<b></b>");

将会得到如下的结果:

<b><strong title="选择你最喜欢的水果." >你最喜欢的水果是?</strong></b>

<b><strong title="选择你最喜欢的水果." >你最喜欢的水果是?</strong></b>

使用wrapAll()方法包裹<strong>元素,jQuery代码如下:

$("strong").wrapAll("<b></b>");

则会得到如下结果:

<b>

<strong title="选择你最喜欢的水果." >你最喜欢的水果是?</strong>

<strong title="选择你最喜欢的水果." >你最喜欢的水果是?</strong>

</b>

2.   wrapInner()方法:

该方法将每一个匹配的元素的子内容(包括文本节点)用其他结构化的标记包裹起来。

例如可以使用它来包裹<strong>标签的子内容,jQuery内容如下:

$("strong").wrapInner("<b></b>");

运行代码后,发现<strong>标签内的内容被一对<b>标签包裹了,结果如下:

<strong title=”选择你最喜欢的水果。”><b>你最喜欢的水果是?</b></strong>

3.2.8  属性操作

在jQuery中,用attr()方法来获取和设置元素属性,removeAttr()方法来删除元素属性。

jQuery代码如下:

var $para=$(“p”);               //获取<p>节点

var p_txt=$para.attr(“title”);        //获取<p>元素节点属性title

如果要设置<p>元素的属性title的值,也可以使用同一个方法,不同的是,需要传递两个参数即名称和对应的值。

jQuery代码如下:

$("p").attr("title","you  title");            //设置单个的属性值。

如果需要一次性为同一个元素设置多个属性,可以使用下面的代码来实现:

$("p").attr({"title":"your  title",”name”:”test”});//将一个“名/值”形式的对象设置为匹配元素的属性

jQuery中的很多方法都是同一个函数实现获取(getter)和设置(setter)的,例如上面的attr()方法,既能设置元素属性的值,也能获取元素属性的值。类似的还有html()、text()、height()、width()、val()和css()等方法。

3.   删除属性

在某些情况下,需要删除文档中某个元素的特定属性,可以使用removeAttr()方法来完成该任务。

如果需要删除<p>元素的title属性,可以使用下面的代码实现;

$("p").removeAttr("title");

运行代码后,<p>元素的title属性将被删除。此时<p>元素的HTML结构由

<p title="选择你最喜欢的水果." >你最喜欢的水果是?</p>

变为

<p>你最喜欢的水果是?</p>

3.2.9  样式操作

1.获取样式和设置样式

HTML代码如下:

<p class="myClass"title="选择你最喜欢的水果." >你最喜欢的水果是?</p>

在上面的代码中,class也是<p>元素的属性,因此获取class和设置class都可以使用attr()来完成。

例如使用attr()方法来获取<p>元素的class,jQuery代码如下:

varp_class=$("p").attr("class")                   //获取<p>元素的class

也可以使用attr()方法来设置<p>元素的class,jQuery代码如下:

$("p").attr("class","high");             //设置<p>元素的class为“high”

在大多数情况下,它是将原来的class替换为新的class,而不是在原来的基础上追加新的class。

运行代码后,上面的HTML代码将变为如下结构:

<p class="high" title="选择你最喜欢的水果.">你最喜欢的水果是?</p>

此处需要的是“追加”效果——class属性变为“myClass high”,即myClass和high两种样式的叠加:

<p class=”myClass high” title=”选择你喜欢的水果”>你最喜欢的水果是?</p>

2. 追加样式

jQuery提供了专门的addClass()方法来追加样式,为了使例子更容易理解,首先在<style>

<style type="text/css">

.high{

     font-weight:bold;   /*粗体字 */

     color : red;        /*字体颜色设置红色 */

}

.another{

/*追加所需的样式 */

font-style:italic;    /*将字体设为斜体 */

color:blue;               /*字体颜色设置蓝色 */

}

</style>

然后在网页中添加一个“追加class类”的按钮,按钮的事件代码如下:

$("#addclassButton").click(function() {

   $("p").addClass("another"); //追加another样式

});

最后当单击”追加class类”按钮时,<p>元素样式就会变成为斜体,而先前的红色字体会变为蓝色,显示效果如图3-14所示

图3-14  addClass()方法

此时<p>元素同时拥有两个class值,即“high”和“another”。在CSS中有以下两条规定。

(1)  如果给一个元素添加了多个class值,那么就相当于合并了它们的样式。

(2)  如果有不同的class设定了同一样式属性,则后者覆盖前者。

在上例中,相当于给<p>元素添加了如下样式:

font-weight:bold;   /*粗体字 */

color :red;        /*字体颜色设置红色 */

font-style:italic;    /*将字体设为斜体 */

color:blue;            /*字体颜色设置蓝色 */

在以上的样式中,存在两个“color”属性,而后面的“color”属性会覆盖前面的“color”属性,因此最终的“color”属性的值为“blue”,而不是“red”。

样式最终呈现为:

font-weight:bold;   /*粗体字 */

font-style:italic;    /*将字体设为斜体 */

color:blue;            /*字体颜色设置蓝色 */

追加样式和设置样式的区别如表3-2所示。

表3-2 attr()和addClass()的区别

方法

addClass()

Attr()

用途

追加样式

设置样式

对同一个网页元素操作

<p>test</p>

第一次使用方法

$("p").addClass("high");

$(“p”).attr(“class”,”high”);

第一次结果

<p class=”high”>high</p>

再次使用方法

$("p").addClass("another”)

$(“p”).attr(“class”,” another”);

最终结果

<p class=”high another”>test</p>

<p class=” another”>test</p>

3. 移除样式

在上面的例子中,为<p>元素追加了another样式。此时<p>元素的HTML代码变为:

<p class=”highanother”>test</p>

如果用户的单击某个按钮时,要删除的某个值,那么可以使用与addClass()方法相反的removeClass()方法来完成,它的作用是从匹配的元素中删除全部或者指定的class。

例如可以使用如下的jQuery代码来删除<p>元素中值为“high”的class

$(“p”).removeClass(“high”);

输出结果为:

<p class=” another”>test</p>

如果要把<p>元素的两个class都删除,就要使用两次removeClass()方法,代码如下:

$("p").removeClass("high").removeClass(“another”);

jQuery提供了更简单的方法。可以以空格的方式删除多个class名,jQuery代码如下;

$("p").removeClass(“highanother”);

另外,还可以利用removeClass()方法的一个特性来完成同样的效果。当它不带参数时,就会将class的值全部删除,jQuery代码如下:

$("p").removeClass();

此时,<p>元素的HTML结构为;

<p>test</p>

4. 切换样式

jQuery中的toggle()方法的代码如下:

$togglebtn.toggle(function(){              //toggle():交替一组动作

//显示元素        代码3

},function(){

   //隐藏元素      代码4

})

Toggle()方法此处的作用是交替执行代码3和代码4两个函数,如果元素原来是显示的,则隐藏它;如果元素原来是隐藏的,则显示它。此时,toggle()方法主要是控制行为上的重复切换。

另外jQuery还提供了一个toggleClass()方法控制样式上的重复切换。如果类名存在则删除它,如果类名不存在则添加它。

例如对<p>元素进行toggleClass()方法操作。

jQuery代码如下:

$(“p”).toggleClass(“another”);   //重复切换类名”another”

当单击“切换模式”按钮后,<p>元素的HTML代码由

<p class=”myClass” title=”选择你喜欢的水果。”>你最喜欢的水果是?</p>

变为

<p class=”myClass another” title=”选择你最喜欢的水果。”>你最喜欢的水果是?</p>

当再次单击“切换模式”按钮后,<p>元素的HTML代码又返回原来的状态:

<p class=” myClass” title=”选择你喜欢的水果。”>你最喜欢的水果是?</p>

当不断单击“切换模式”按钮时,<p>元素的class的值就会在“myClass”和“myClass another”之间重复切换。

5. 判断是否含有某个样式

hasClass()可以用来判断元素中是否含有某个class,如果有,则返回true,否则返回false。

例如可以使用下面的代码来判断<p>元素中是否含有“another”的class:

$(“p”).hasClass(“another”);

这个方法是为了增强代码可读性而产生的。在jQuery内部实际上是调用了is()方法来完成这个功能的。该方法等价于如下代码:

$(“p”).is(“.another”);     //is(“.”+class)

3.2.10  设置和获取HTML、文本和值

1.html()方法

此方法类似于javascript中的innerHTML属性,可以用来读取或者设置某个元素中的HTML内容。

为了更清楚地展示效果,将<p>元素的HTML代码改成:

<p title=”选择你最喜欢的水果。”><strong>你最喜欢的水果是?</strong></p>

然后用html()方法对<p>元素进行操作:

var p_html = $(“p”).html();   //获取<p>元素的html代码

alert(p_html);            //打印<p>元素的HTML代码

运行代码后,效果如图3-15所示。

如果需要设置某元素的HTML代码,那么也可以使用该方法,不过使用该方法,不过需要为它传递一个参数。例如要设置<p>元素的HTML代码,可以使用如下代码:

$(“p”).html(“<strong>你最喜欢的水果是?</Strong>”);

注意:html()方法可以使用XHTML文档,但不能用于XML文档。

2.text()方法

此方法类似于JavaScript中的innerText属性,可以用来读取后或者设置某个元素中的文本内容。

继续使用以上的HTML代码:

<p title=”选择你喜欢的水果”><strong>你最喜欢的水果是?</strong></p>

用text()方法对<p>元素进行操作:

var p_text=$(“p”).text();            //获取<p>元素的文本内容

alert(p_text);                       //打印<p>元素的文本内容

运行代码后,效果如图3-16所示:


图3-15 获取<p>元素的HTML代码

 

图3-16获取<p>元素的文本内容


与html()方法一样,如果需要为某元素设置文本内容,那么也需要传递一个参数。例如对<p>元素设置文本内容,代码如下:

$(“p”).text(“你最喜欢的水果是?”);            //设置<p>元素的文本内容

3.val()方法

此方法类似于javascript中的value属性,可以用来设置和获取元素的值。无论元素是文本框,下拉列表还是单选框,它都可以返回元素的值。如果元素为多选,则返回一个包含所有选择的值的数组。

另外,val()方法还有另外一个用处,就是它能使select(下拉列表框)、checked(多选框)和radio(单选框)相应的选项被选中,在表单操作中会经常用到。

下面构建一个网页来演示val()方法的选中功能。

HTML代码如下:

<select id="single">

 <option>选择1号</option>

 <option>选择2号</option>

 <option>选择3号</option>

</select>

<select id="multiple"multiple="multiple" style="height:120px;">

 <option selected="selected">选择1号</option>

 <option>选择2号</option>

 <option>选择3号</option>

 <option>选择4号</option>

 <option selected="selected">选择5号</option>

</select>

<br/><br/>

<input type="checkbox"value="check1"/> 多选1

<input type="checkbox"value="check2"/> 多选2

<input type="checkbox"value="check3"/> 多选3

<input type="checkbox"value="check4"/> 多选4

<br/>

<input type="radio"value="radio1"/> 单选1

<input type="radio"value="radio2"/> 单选2

<input type="radio"value="radio3"/> 单选3

运行代码后,显示效果如图3-17所示。

该网页中一些元素是默认被选中的,可以通过val()方法来改变它们的选中项。如果要是第一个下拉框的第二项被选中,可以用以下jQuery代码实现:

$("#single").val("选择2号");

如果要使下拉列表框的第二项和第三项被选中,可以用以下jQuery代码实现:

 $("#multiple").val(["选择2号", "选择3号"]);      //以数组的形式赋值

依照上面类似的写法,下面的代码可以使多选框和单选框被选中,jQuery代码如下:

$(":checkbox").val(["check2","check3"]);

$(":radio").val(["radio2"]);

运行代码后,显示效果如图3-18所示。


图3-17 初始化

图3-18 设置多选框和单选框


3.2.11  遍历节点

1.Children()方法

该方法用于取得匹配元素的子元素集合。

此处使用本章开头所画的那颗DOM树的结构,如图3-19所示。

 

图3-19 DOM树

根据DOM树的结构,可以知道各个元素之间的关系以及他们之间的子节点的个数。<body>元素下有<p>和<ul>两个子元素,<p>元素没有子元素,<ul>元素有3个<li>子元素。

下面使用children()方法来获取匹配元素的所有子元素的个数。

JQuery代码如下:

var $body = $("body").children();

       var $p = $("p").children();

       var $ul = $("ul").children();

       alert( $body.length );  // <body>元素下有2个子元素

       alert( $p.length );     // <p>元素下有0个子元素

       alert( $ul.length );    // <p>元素下有3个子元素

       for(var i=0;i< $ul.length;i++){

       alert( $ul[i].innerHTML );

       }

注意:children()方法只考虑子元素而不考虑任何的后代元素。

2.next()方法

该方法用于取得匹配元素后面紧邻的同辈元素。

从DOM树的结构中可以知道<p>元素的下一个同辈节点是<ul>,因此可以通过 next()方法类获取<ul>元素,代码如下:

var $p1  =  $("p") . next();    //获取紧邻<p>元素后的同辈元素

得到的结果将是:

<ul>

       <li title='苹果'>苹果</li>

       <li title='橘子'>橘子</li>

       <li title='菠萝'>菠萝</li>

</ul>

3.prev()方法

该方法用于取得匹配元素前面紧邻的同辈元素。

从DOM树的结构中可以知道<ul>元素的上一个同辈节点是<p>,因此可以通过prev()方法获取<p>元素,代码如下:

var $ul  =  $("ul") . prev();    //获取紧邻<ul>元素前的同辈元素

得到的结果将是:

<p title="选择你最喜欢的水果." >你最喜欢的水果是?</p>

4.siblings()方法

该方法用于取得匹配元素前后所有的同辈元素。

以DOM树的结构为例。<ul>元素和<p>元素互为同辈元素,<ul>元素下的3个<li>元素也互为同辈元素。

如果要获取<p>元素的同辈元素,则可以使用如下的代码:

var $p2=$("p").siblings();//获取紧邻<p>元素的同辈元素

得到的结果将是:

<ul>

        <li title='苹果'>苹果</li>

        <li title='橘子'>橘子</li>

        <li title='菠萝'>菠萝</li>

      </ul>

5.closest()

它用来获取最近的匹配元素。首先检查当前元素是否匹配,如果匹配则直接返回元素本身。如果不匹配则向上查找父元素,逐级向上直到找到匹配选择器的元素。如果什么都没找到则返回一个空的jQuery对象。

比如,给点击的目标元素的最近的li元素添加色彩可以使用如下代码:

$(document).bind("click",function (e) {

             $(e.target).closest("li").css("color","red");

      })

除此之外,在jQuery中还有很多遍历节点的方法,例如find(),filter(),nextAll(),prevAll(),parent()等,此处不再说明,读者可以查看附录的jQuery速查表文档。值得注意的是,这些遍历DOM方法有一个共同的特点,都可以使用jQuery表达式作为他们的参数来筛选元素。

3.2.12  CSS-DOM操作

CSS-DOM技术简单来说就是读取和设置style对象的各种属性。Style属性很有用,但最大的不足是无法通过它来提取到通过外部CSS设置的样式信息,然而在jQuery中,这些都是非常的简单。

可以直接用css()方法获取元素的样式属性,jQuery代码如下:

$("p").css("color");//获取<p>元素的样式颜色

无论color属性是外部css导入,还是直接拼接在HTML元素里(内联),css()方法都可以获取到属性style里的其他属性的值。

也可以直接利用css()方法设置某个元素的单个样式,例如:

$("p").css("color","red");//设置<p>元素的样式的颜色是红色

与attr()方法一样,css()方法也可以同时设置多个样式属性,代码如下:

$("p").css({"fontSize":"30px","backgroundColor":"#888888"});//同时设置字体大小和背景色

对透明度的设置,可以直接使用opacity属性,jQuery已经处理好了兼容性的问题,如下代码所示,将<p>元素的透明度设置为半透明:

$("p").css("opacity","0.5");

如果要获取某个元素的height属性,则可以通过如下jQuery代码实现:

$(element).css("height");

在jQuery中还有另外一种方法也可以获取元素的高度,即height()。它的作用是获取匹配元素当前计算的高度值(px)。jQuery代码如下:

$("p").height();//获取<p>元素的高度值

height()方法也能用来设置元素的高度,如果传递的值是一个数字,则默认单位为px。如果要用其他的单位(例如em)则必须传递一个字符串。jQuery代码如下:

$("p").height(100);//获取<p>元素的高度值为100px

$("p").height("10em");//获取<p>元素的高度值为10em

与height()方法对应的还有一个width()方法,他还可以获取匹配元素的宽度(px)。

$("p").width();//获取<p>元素的宽度值;

同样,width()方法也能来设置元素的宽度。

$("p").width("400px");//设置<p>元素的宽度值为400px

此外,在CSS-DOM中还有以下几个经常使用的方法。

1.offset()方法

它的作用是获取元素在当前窗口的相对偏移,其中返回的对象包括两个属性,即top和left,他只对可见元素有效。例如用它来获取<p>元素的偏移量,jQuery代码如下:

 varoffset = $("p").offset();      //获取<p>元素的offset()

 varleft = offset.left;              //获取做左偏移

 vartop =  offset.top;               //获取右偏移

2.Position()方法

它的作用是获取元素相对于最近的一个position样式属性设置为relative或者absolute的祖父节点的相对偏移,与offset()一样,它返回的对象也包括两个属性,即top和left。jQuery代码如下:

 varposition= $("p").position();      //获取<p>元素的offset()

 varleft = position.left;              //获取做左偏移

 vartop =  position.top;            //获取右偏移

3.scrollTop()方法和scrollLeft()方法

这两个方法的作用分别是获取元素的滚动条距顶端的距离和距左侧的距离。例如使用下面的代码获取<p>元素的滚动条距离:

 var$p= $("p");

 varscrollTop= $p.scrollTop();           //获取元素的滚动条距顶端的距离

 varscrollLeft=  $p.scrollLeft();         //获取元素的滚动条距左侧的距离

另外,可以为这两个方法指定一个参数,控制元素的滚动条滚动到指定位置。例如使用如下代码控制元素内的滚动条滚动到距顶端300和距左侧300的位置:

$("textarea").scrollTop(300);      //元素的垂直滚动条滚动到指定的位置

$("textarea").scrollLeft(300);     //元素的横向滚动条滚动到指定的位置

至此,已经将jQuery中常用的DOM操作(包括DOM Core,HTML——DOM和CSS-DOM)都已经介绍完毕。以下将结合这些方法,研究一个融合了DOM操作的实例

3.3 案例研究----某网站的超链接和图片提示效果

在这一节中,将以某网站的超链接和图片提示效果为例,来理解和巩固jQuery中的DOM操作。

1.  超链接提示效果

浏览器已经自带了超链接提示,只需在超链接中加入title属性就可以了。

HTML代码如下:

<ahref="#" title="这是我的超链接提示1.">提示</a>

然而这个提示效果的响应速度是非常缓慢的,考虑到良好的人际交互,需要的是当鼠标移到超链接的那一瞬间就出现提示。这时就需要移除<a>标签中的title提示效果,自己动手做一个类似功能的提示。

首先在空白的页面上,添加两个普通超链接和两个带有class的超链接。

HTML代码如下:

<p><a href="#"class="tooltip" title="这是我的超链接提示1.">提示1.</a></p>

<p><a href="#"class="tooltip" title="这是我的超链接提示2.">提示2.</a></p>

<p><a href="#"title="这是自带提示1.">自带提示1.</a></p>

<p><a href="#"title="这是自带提示2.">自带提示2.</a></p>

然后为class为tooltip的超链接添加mouseover和mouseout事件,jQuery代码如下:

$("a.tooltip").mouseover(function(){

           //显示title

}).mouseout(function(){          

             //隐藏title

   });

实现这个效果的具体思路如下。

(1) 当鼠标滑入超链接。

①创建一个<div>元素,<div>元素的内容为title属性的值。

②将创建的元素追加到文档中。

③为它设置x坐标和y坐标,使他显示在鼠标位置的旁边。

(2) 当鼠标滑出超链接时,移除<div>元素。

根据分析的思路,写出如下jQuery代码:

$(function(){

   $("a.tooltip").mouseover(function(e){

var tooltip = "<div id='tooltip'>"+this.myTitle +"<\/div>"; //创建 div 元素

             $("body").append(tooltip);       //把它追加到文档中

             $("#tooltip") .css({

                           "top":(e.pageY) + "px",

                           "left":(e.pageX) + "px"

                    }).show("fast");      //设置x坐标和y坐标,并且显示

   }).mouseout(function(){        

$("#tooltip").remove();   //移除

   });

});

运行效果,如图3-20所示。

图3-20 超链接提示

此时的效果有两个问题:首先是当鼠标滑过后,<a>标签的title属性的提示也会出现;其次是设置x坐标和y坐标的问题,由于自制的提示与鼠标距离太近,有时会引起无法提示的问题(鼠标焦点变化引起mouseout事件)。

为了移除<a>标签的title提示功能,需要进行以下的几个步骤。

(1) 当鼠标滑入时,给对象添加一个新属性,并把tilte的值传给这个属性,然后清空属性tilte的值。

jQuery代码如下:

This.myTitle=this.title;

this.title="";

var tooltip="<div id='tooltip'>"+this.myTitle+"</div>";//创建<div>元素

(2) 当鼠标滑出时,再把对象的myTitle属性的值有赋给title

jQuery代码如下:

  this.title= this.myTitle;

为了解决第二个问题,需要重新设置提示元素的top和left的值,代码如下所示,为top增加了10px,为left增加了20px:

var x=10;

var y=20;

$(“#tooltip”).css({

      “top”:(e.pageY+y)+”px”;

      “left”:(e.pageX+x)+”px”;

})

解决了这个问题后,完整的代码如下:

$(function(){

     var x=10;

     var y=20;

     $(“a.tooltip”).mouseover(function(e){

    this.myTitle=this.title;

    this.title=““;

var tooltip=“<div id=’tooltip’>“+this.myTitle+”</div>“; //创建div元素

         $(“body”).append(tooltip);     //将它追加到文档中

$(“#tooltip”) .css({

           “top”:(e.pageY+y)+”px”,

           “lefe”:(e.pageX+x)+”px”;

}).show(“fast”);              设置x坐标和y坐标并且显示

}).mouseout(function(){

this.title=this.myTitle;

$(“#tooltip”).remove();              //移除

});

})

此时,鼠标滑入和滑出显示已经没问题了,但鼠标在超链接上移动时,提示效果并不会跟着鼠标移动,如果需要提示效果跟着鼠标移动,可以为超链接加一个mousemove事件,jQuery代码如下:

$(“a.tooltip”).mousemove(function(e){

                    $(“#tooltip”).css({

          “top”:(e.pageY+y)+”px”,

          “lefe”:(e.pageX+x)+”px”;

});

});

这样,当鼠标在超链接上移动时,提示效果也会跟着移动了。

图3-21 提示效果

到此,超链接提示效果就完成了。完整的jQuery代码如下:

      $(function(){

             varx=10;

             vary=20;

             $(“a.tooltip”). mousemove(function(e){

             this.myTitle=this.title;

             this.title=““;

vartooltip=“<div id=’tooltip’>“+this.myTitle+”</div>“;//创建div元素

$(“body”).append(tooltip);     //将它追加到文档中

$(“#tooltip”)       .css({

        “top”:(e.pageY+y)+”px”,

        “left”:(e.pageX+x)+”px”;

}).show(“fast”);         设置x坐标和y坐标并且显示

}).mouseout(function(){

                this.title=this.myTitle;

                $(“#tooltip”).remove();//移除

         }).mousemove(function(e){

                $(“#tooltip”) .css({

          “top”:(e.pageY+y)+”px”,

          “lefe”:(e.pageX+x)+”px”;

                });

});

});

2.图片的提示效果

稍微修改上面的代码,就可以做出一个图片的提示效果。

首先在空白页中加入图片,HTML代码如下:

<ul>

             <li><ahref="images/apple_1_bigger.jpg" class="tooltip"title="苹果 iPod"><imgsrc="images/apple_1.jpg" alt="苹果 iPod" /></a></li>

             <li><ahref="images/apple_2_bigger.jpg" class="tooltip"title="苹果 iPodnano"><img src="images/apple_2.jpg" alt="苹果 iPod nano"/></a></li>

             <li><ahref="images/apple_3_bigger.jpg" class="tooltip"title="苹果iPhone"><img src="images/apple_3.jpg" alt="苹果 iPhone"/></a></li>

             <li><ahref="images/apple_4_bigger.jpg" class="tooltip"title="苹果 Mac"><imgsrc="images/apple_4.jpg" alt="苹果 Mac"/></a></li>

      </ul>

设置样式后,初始化效果如图3-22所示。

图3-22 初始化效果

参考前面超链接提示效果的代码,只需要将创建的<div>元素的代码由

var tooltip ="<div id='tooltip'>”+this.Mytitle+”<\/div>";//创建div元素

改为

var tooltip ="<div id='tooltip'><img src='"+ this.href +"' alt='产品预览图'/><\/div>";//创建 div 元素

就可以了。当鼠标滑过后,显示效果如3-23所示。

图3-23 图片提示效果

为了使效果更人性化,还要为图片增加文字,即提示出来的大图片下面出现出现图片相应的文字介绍。

可以根据超链接的title属性值来获得图片相应的介绍文字,jQuery代码如下:

      this.myTitle=this.title;

      this.title=““;

varimgTitle=this.myTitle?”<br/>“+this.myTitle:”“;

然后将它追加到<div>元素中代码如下:

var tooltip="<divid='tooltip'><img src='"+this.href+"' alt='产品

预览图'/>"+imgTitle+"</div>";

这样,图片提示效果就完成了,当鼠标滑过图片时,图片会出现预览的大图,大图下面还会有介绍文字。效果如图3-24所示。

图3-24 图片提示效果

完整的jQuery代码为:

$(function(){

             varx=10;

             vary=20;

             $(“a.tooltip”). mouseover(function(e){

           this.myTitle=this.title;

           this.title=““;

           varimgTitle=this.myTitle?"<br/>"+this.myTitle:"";

           vartooltip="<div id='tooltip'><img src='"+this.href+"'            alt='产品预览图'/>"+imgTitle+"</div>";   //创建<div>元素

           $(“body”).append(tooltip);     //将它追加到文档中

           $(“#tooltip”) .css({

                  “top”:(e.pageY+y)+”px”,

                  “lefe”:(e.pageX+x)+”px”;

           }).show(“fast”);             设置x坐标和y坐标并且显示

                    }).mouseout(function(){

                    this.title=this.myTitle;

                    $(“#tooltip”).remove();            //移除

             }).mousemove(function(e){

    $(“#tooltip”) .css({

           “top”:(e.pageY+y)+”px”,

           “lefe”:(e.pageX+x)+”px”;

           });

});

});

到此,超链接提示和图片提示效果都完成了。此处仅仅用了jQuery中的几个DOM操作方法,就完成了很友好的动态提示效果。

四、 jQuery中的事件和动画

javaScript和HTML之间的交互式通过用户和浏览器操作页面时引发的事件来处理的。当文档或者它的某些元素发生某些变化或操作时,浏览器会自动生成一个事件。例如当浏览器装载完一个文档后,会生成事件;当用户单击某个按钮时,也会生成事件。虽然利用传统的javaScript事件完成这些交互,但jQuery增加并扩展了基本处理机制。jQuery不仅提供了更加优雅的事件处理语法,而且极大地增强了事件处理能力。

4.1 jQuery中的事件

4.1.1  加载DOM

以浏览器装载文档为例,在页码加载完毕后,浏览器会通过javaScript为DOM元素添加事件。在常规的javaScript代码中,通过使用windows.onload方法,而在jQuery中,使用的是$(document).ready()方法。$(document).ready()方法是事件模块中重要的一个函数,可以极大地提高Web应用程序的影响速度。jQuery就是用$(document).ready()方法来代替传统javaScript的 window.onload方法的。通过使用该方法,可以在DOM载入就绪时就对其进行操纵并调用执行它所绑定的函数。在使用过程中,需要注意$(document).ready()方法和window.onload方法之间的细微区别。

1.   执行时机

$(document).ready()方法和window.onload方法有相似功能,但是在执行时方法有区别的。window.onload方法是在网页中所有的元素(包括元素的所有关联文件) 完全加载到浏览器后才执行,既javaScript此时才可以访问网页中的任何元素。而通过jQuery中的$(document).ready()方法注册的事件处理程序,在DOM完全就绪就可以被调用。此时,网页的所有元素对jQuery而言都是可以访问的,但是,这并不意味着这些关联的文件已经下载完毕。

举一个例子,有一个大型的图库网站,为网页中所有图片添加某些行为,例如单击图片后让它隐藏或显示。如果使用window.onload方法来处理,那么用户必须到每一张图片都加载完毕后,才可以进行操作。如果使用jQuery中的$(document).ready()方法来进行设置只要DOM就绪就可以操作了,不需要等待所有图片下载完毕。很显然,把网页解析为DOM树的速度比把页面中的所有关联文件加载完毕的速度快很多。

另外,需要注意一点,由于在$(doument).ready()方法内注册的事件,只要DOM就绪就会执行,因此可能此时元素的关联文件未下载完。例如与图片有关的HTML下载完毕,并且已经解析为DOM树了,但很有可能图片还未加载完毕,所以例如图片的高度和宽度这样的属性此时不一定有效。要解决这个问题,可以使用jQuery中另一个关于页面加载的方法----load()方法。load()方法会在元素的onload事件中绑定一个处理函数。如果处理函数绑定给window对象,则会在所有内容(包括窗口,框架,对象和图像等)加载完毕后触发,如果处理函数绑定在元素上,则会在元素的内容加载完毕后触发。jQuery代码如下:

      $(window).load(function{

             //编写代码

      })

等价于javaScript中的一下代码:

      window.οnlοad=function(){

             //编写代码

      }

2.多次使用

第一章曾经用一个表格(表1-1)总结过window.onload方法和$(document).ready()方法的区别,现在进行详细讲解。

假设网页中有两个函数,javaScript代码如下:

      functionone(){

             alert("one");

      }

      functiontwo(){

             alert("two");

      }

当网页加载完毕后,通过如下JavaScript代码来分别调用one函数和two函数:

      window.οnlοad=one;

      window.οnlοad=two;

然而当运行代码后,发现只弹出字符串“two”对话框。

字符串“one”对话框不能被弹出的原因是javaScript的onload事件一次只能保存对一个函数的引用,它会自动用后面的函数覆盖前面的函数,因此不能在现有的行上添加新的行为。

为了达到两个函数顺序触发的效果,只能再创建一个新的javaScript方法来实现,javaScript代码如下:

window.οnlοad=function(){

     one();

     two();

}

虽然这样编写代码能解决某些问题,但还是不能满足某些需求,例如有多个javaScript文件,每个文件都需要用到window.onload方法,这种情况下用上面提到的方法编写代码会非常麻烦。而jQuery的$(document).ready()方法能够很好地处理这些情况,每次调用$(document).ready()方法都会在现有的行为上追加新的行为,这些行为函数根据注册的顺序依次执行。例如如下jQuery代码:

function one(){

      alert("one");

}

function two(){

      alert("two");

}

$(document).ready(function(){

      one();

})

$(document).ready(function(){

      two();

})

运行代码后,先回弹出字符串“one”对话框,然后弹出字符串“two”对话框。

3.   简写方法

如果读者注意过本书前几章的例子,会发现例子中并不是用的下面的代码:

   $(document).ready(function(){

      //编写代码

   })

而是用的下面代码:

   $(function(){

      //编写代码

   })

后者是前者的简写方式。

另外,$(document)也可以简写为$().当$()不带参数时。默认参数就是“document”,因此可以简写为:

   $().ready(function(){

      //编写代码

   })

3种方式都是一样的功能,读者可以根据自己的喜好,选择其中一种。

4.1.2  事件绑定

在文档装载完成后,如果打算为元素绑定事件来完成某些操作,则可以使用bind()方法来对匹配元素进行特定事件的绑定,bind()方法的调用格式为:

bind(type [,data],fn);

bind()方法有3个参数,说明如下。

第一个参数是事件类型,类型包括:blur、focus、load、resize、scroll、unload、click、dblclick、mousedown、mouseup、mouseover、mouseout、mouseenter、mouseleave、change、select、submit、keydown、keypress、keyup和error等,当然也可以是自定义名称。

第2个参数为可选参数,作为event.data属性值传递给事件对象的额外数据对象。

第3个参数则是用来绑定的处理函数。

1.   基本效果

下面通过一个示例来了解bind()方法的用法。

假设网页中有一个FAQ,单击“标题”链接将显示内容。

HTML代码如下:

<divid="panel">

      <h5class="head">什么是jQuery?</h5>

      <divclass="content">

jQuery是继prototype之后又一个优秀的Javascript库,它是一个由JohnResig创建于2006年1月的开源项目。jQuery凭借简洁的语法和跨平台的兼容性,极大地简化了Javascript开发人员遍历HTML文档,操作DOM,处理事件,执行动画和开发Ajax。它独特而又优雅的代码风格改变了Javascript程序员的设计思路和编写程序的方式。

      </div>

</div>

应用CSS样式表后,网页效果图如图4-1所示。

图4-1 网页初始化效果图

按照需求,需要完成以下几个步骤。

(1)等待DOM装载完毕。

(2)找到“标题”所在的元素,绑定click事件

(3)找到“内容”元素,将“内容”元素显示。

根据分析的步骤,可以轻易地写出如下jQuery代码:

   $(function(){

             $("#panelh5.head").bind("click",function(){

                    $(this).next("div.content").show();

             })

})

运行代码,单击“标题”链接,“内容”就展开了,效果如图4-2所示。

图4-2 显示内容

在上面的例子中,为“标题”绑定了一个click事件,单击标题链接后,显示“内容”。

与ready()方法一样,bind()方法也可以多次调用。

上面jQuery代码中有一个关键字this,与在javaScript中的作用一样,this引用的是携带相应行为的DOM元素。为了使该DOM元素能够使用jQuery中的方法,可以使用$(this)将其转换为jQuery对象(具体实现方法参见第一章1.4.2小节jQuery对象和DOM对象的相互转换)。

2.   加强效果

在上面的例子中,单击“标题”链接显示出“内容”;再次单击“标题”链接,“内容”并没有任何反应。现在需要加强效果:第2次单击“标题”链接,“内容”隐藏;再次单击“标题”链接,“内容"又显示,两个动作循环出现。为了实现这个功能,需要经过以下几个步骤。

(1)等待DOM装载完毕。

(2)找到”标题“所在的元素,绑定click事件。

(3)找到”内容“元素,如果”内容“元素是显示的,则隐藏,如果”新闻内容“元素是隐藏的,则显示。

加强效果的第(3)步要做判断,原理如下:

      if("内容" 显示){

             "内容" 隐藏

      }else{

             "内容" 显示

      }

为了判断元素是否显示,可以使用jQuery中的is()方法来完成。jQuery代码如下:

      $(function(){

             $("#panelh5.head").bind("click",function(){

                    if($(this).next("div,content").is(":visible")){  //如果”内容显示“

                           $(this).next("div.content").hide();

                    }else{

                           $(this).next("div.content").show();

                    }

             })

      })

在代码中,发现$(this).next("div.content")被多次使用,因此可以为它定义一个局部变量:

      var$content=$(this).next("div.content");

然后把局部变量引入到代码中,改进后的jQuery代码如下:

      $(function(){

             $("#panelh5.head").bind("click",function(){

                    var$content=$(this).next("div.content");

                    if($content.is(":visible")){

                           $content.hide();

                    }else{

                           $content.show();

                    }

             })

      })

通过以上的修改,可以实现加强效果。当反复地单击“标题”链接时,“内容”会在隐藏和显示两种状态下切换。

3.   改变绑定事件类型

上面的例子中,给元素绑定的事件类型是click,当用户单击的时候会触发绑定的事件,然后执行事件的函数代码。现在把事件类型换成mouseover和mouseout,即当光标滑过的时候,就触发事件。需要进行以下几步操作。

(1)等待DOM装载完毕。

(2)找到“标题”所在的元素,绑定mousrover事件。

(3)找到“内容”元素,显示“内容”。

(4)找到“标题”所在的的元素,绑定mouseout事件。

(5)找到“内容”元素,隐藏“内容”。

根据分析的步骤,可以写出如下jQuery代码:

      $(function(){

             $("#panelh5.head").bind("mouseover",function(){

                    $(this).next("div.content").show();

             });

             $("#panelh5.head").bind("mouseout",function(){

                    $(this).next("div.content").hide();

             })

      })

代码运行后,当光标滑过“标题”链接后,相应的“内容”将被显示,如图4-3所示。当光标滑出“标题”链接后,相应的“内容”则被隐藏,如图4-4所示。


图4-3 内容显示

图4-4 内容隐藏



在上面几个例子中,分别用bind()方法给”标题“绑定了click事件,mouseover事件和mouseout事件,绑定方法都一样。除此之外,bind()方法还能绑定javaScript事件。

4.   简写绑定事件

像click,mouseover和mouseout这类事件,在程序中经常会用到,jQuery为此也提供了一套简写的方法。简写方法和bind()的使用类似,实现的效果也相同,唯一的区别是能够减少代码量。

例如把上面的例子改写成使用简写绑定事件的方式,代码如下:

      $(function(){

             $("$panelh5.head").mouseover,function(){

                    $(this).next("div.content").show();

             });

             $("$panelh5.head").mouseout(function(){

                    $(this).next("div.content").hide();

             })

      });

4.1.3  合成事件

jQuery有两个合成事件:hover()方法和toggle()方法,类似前面讲过的ready()方法,hover()方法和toggle方法都属于jQuery自定义的方法。

1.hover()方法

hover()方法的语法结构为:

hover(enter,leave);

hover()方法使用模拟光标悬停事件。当光标移动到元素上时,会触发指定的第一个函数(enter);当光标移出这个元素时,会触发指定的第2个函数(leave)。

将上面的例子改成成使用hover() 方法,jQuery代码如下:

      $(function(){

             $("#panelh5.head").hover(function(){

                    $(this).next("div.content").show();

             },function(){

                    $(this).next("div.content").hide();

             });

      })

代码运行后效果与下面代码运行后的效果是一样的。当光标滑过”标题“链接时,相应的“内容”将被显示;当光标滑过“标题”链接后,相应的“内容”则被隐藏。

$(function(){

             $("#panelh5.head").mouseover(function(){

                    $(this).next("div.content").show();

             });

             $("#panelh5.head").mouseout(function(){

                    $(this).next("div.content").hide();

             })

      })

2.toggle()方法

toggle()方法的语法结构为:

      toggle(fn1,fn2,...fnN);

toggle()方法用于模拟鼠标连续单击事件。第1次单击元素,触发指定的第一个函数(fn1);当再次单击同一个元素时,则触发指定的第2个函数(fn2);如果有更多函数,则依次发,直到最后一个。随后的每次单击都重复对几个函数的轮番调用。

在前面的加强效果的例子中,使用了以后jQuery代码:

      $(function(){

             $("#panelh5.head").bind("click",function(){

                    var$content=$(this).next("div.content");

                    if($content.is(":visible")){

                           $content.hide();

                    }else{

                           $content.show();

                    }

             })

      });

虽然上面的代码能实现需要的效果,但是选择的方法并不是最适合的。因此需要连续单击“标题”链接,来达到使“内容”隐藏和显示的目的,所以很适合使用toggle()方法。原理如下:

      $(标题).toggle(function){

             //内容显示

      },function(){

             //内容隐藏

      });

使用toggle()方法来改写上面的例子,jQuery代码如下:

      $(function(){

             $("#panelh5.head").toggle(function(){

                    $(this).next("div.content").show();

             },function(){

                    $(this).next("div.content").hide();

             });

      })

通过使用toggle()方法不仅实现了同样的效果,同时也简化了代码。

toggle()方法在jQuery中还有另外一个作用:切换元素的可见状态。如果元素是可见的,单击切换后则为隐藏;如果元素是隐藏的,单击后则为可见的。因此上面的代码还可以写成如下jQuery代码:

      $(function(){

             $("#panelh5.head").toggle(function(){

                    $(this).next("div.content").toggle();

             },function(){

                    $(this).next("div.content").toggle();

             });

      })

3.再次加强效果

为了能有更好的用户体验,现在需要在用户单击“标题”链接后,不仅显示“内容”而且高亮显示“标题”。为了完成这样一功能,首先在CSS中定义一个高亮的样式,CSS代码如下:

      .highlight{

             background:#FF3300;

      }

接下来需要完成以下几个步骤。

(1)等待DOM装载完毕。

(2)找到“标题”元素,添加toggle()方法,在toggle()方法定义两个函数,分别代表显示和隐藏。

(3)在显示函数里,给“标题”添加高亮class.

(4)在隐藏函数里,移除“标题”的高亮class。

然后编写如下jQuery代码:

      $(function(){

             $("#panelh5.head").toggle(function(){

                    $(this).addClass("highlight");   //添加高亮样式

                    $(this).next("div.content").show();

             },function(){

                    $(this).removeClass("highlight");  //移除高亮样式

                    $(this).next("div.content").hide();

             });

      })

运行代码后,如果“内容”是显示的,“标题”则会高亮显示;如果“内容”是隐藏的,则不会高亮显示“新闻标题”,显示如图4-5和图4-6所示效果。

图4-5 显示时,高亮状态

图4-6 隐藏时,非高亮状态

4.1.4  事件冒泡

1.什么是冒泡

在页面上可以有多个事件,也可以多个元素响应同一个事件。假设网页上有两个元素,其中一个元素嵌套在另一个元素里,并且都被绑定了click事件,同时<body>元素上也绑定了click事件。

完整代码如下:

      <scripttype="text/javascript">

      $(function(){

// 为span元素绑定click事件

      $('span').bind("click",function(){

             vartxt = $('#msg').html() + "<p>内层span元素被点击.<p/>";

             $('#msg').html(txt);

      });

      //为div元素绑定click事件

      $('#content').bind("click",function(){

          var txt = $('#msg').html() +"<p>外层div元素被点击.<p/>";

             $('#msg').html(txt);

      });

      //为body元素绑定click事件

      $("body").bind("click",function(){

             vartxt = $('#msg').html() + "<p>body元素被点击.<p/>";

             $('#msg').html(txt);

      });

})

</script>

<div id="content">

      外层div元素

      <span>内层span元素</span>

      外层div元素

</div>

<div id="msg"></div>

页面初始化效果如图4-7所示。

当单击内部<span>元素,即触发<span>元素的click事件时,会输出3条记录,如图4-8所示。     

图4-7 初始化效果

图4-8 单击内部元素

只单击内部<span>元素,就会触发外部<div>元素和<body>元素上绑定的click事件。这是由事件冒泡引起的。

在单击<span>元素的同时,也单击了包含<span>元素的元素 <div>和包含<div>元素的元素<body>,并且每个元素都会按照特定的顺序相应的click事件。

元素的click事件会按照以下顺序“冒泡”。

(1)<span>

(2)<div>

(3)<body>

之所以称为冒泡,是因为事件会按照DOM的层次结构像水泡一样不断向上直至顶端。

2.事件冒泡引发的过程

事件冒泡可能会引起预料之外的效果。上例中,本来只想触发<span>元素的click事件,然而<div>元素和<body>元素的click事件也同时被触发了。因此,有必要对事件的作用范围进行限制。当单击<span>元素时,只触发<span>元素的click事件;当单击<div>元素时,只触发<div>元素的click事件,而不触发<body>元素click事件,为了解决这些问题,介绍以下内容。

事件对象

由于IE-DOM和标准DOM实现事件对象的方法各不相同,导致不同的浏览器中获取事件对象变得比较困难。针对这个问题,jQuery进行了必要的扩展和封装,从而使得在任何浏览器中都能很轻松地获取事件对象以及事件对象的一些属性。

在程序中使用事件对象非常简单,只需要为函数添加一个参数,jQuery代码如下:

$('element').bind("click",function(event){  // event事件对象

//………..

}

这样,当单击“element”元素时,事件对象就被创建了。这个事件对象只有事件处理函数才能访问到,事件处理函数执行完毕后,事件对象就被销毁。

停止事件冒泡

停止事件冒泡可以阻止事件中其他对象的事件处理函数被执行。在jQuery中stopPropagation()方法来停止事件冒泡。

jQuery代码如下:

$(“span”).bind(“click”,function(event){

Var txt=$(“#msg”).html()+”<p>内层span元素被单击.</p>”

$(“#msg”).html(txt);

Event.stopPropagation();

});

当单击<span>元素时, 只会触发<span>元素上的click事件,而不会触发<div>元素和<body>的元素的click事件。

可以用同样的方法解决<div>元素上的冒泡问题。

jQuery代码如下:

$(“#content”).bind(“click”,function(event){

  vartxt=$(“#msg”).html()+”<p>外层div元素被单击.</p>”

  $(“#msg”).html(txt);

  Event.stopPropagation();

});

这样,当单击<span>元素或者<div>元素时,就只会输出相应的内容,而不会输出其他的内容,效果如图4-9所示。

图4-9 单击span元素时

阻止默认行为

网页中的元素有自己默认的行为,例如,单击超链接后会跳转、单击“提交”按钮后表单会提交,有时需要阻止元素的默认行为。在jQuery中,提供了preventDefault()方法来阻止元素的默认行为。举一个例子,在项目中,经常需要验证表单,在单击“提交”按钮时,验证表单内容,例如某元素是否是必填字段,某元素长度是否够6位等,当表单不符合提交条件时,要阻止表单的提交(默认行为)。

代码如下:

<scripttype="text/javascript">

$(function(){

  $("#sub").bind("click",function(event){

        var username = $("#username").val();  //获取元素的值

        if(username==""){     //判断值是否为空

                  $("#msg").html("<p>文本框的值不能为空.</p>");  //提示信息

event.preventDefault();// 阻止默认行为(表单提交)

                  }

})

</script>

<form action="loadtest.htm">

用户名:<inputtype="text" id="username" />

<br/>

<input type="submit" value="提交" id="sub"/>

</form>

<div id="msg"></div>

用户名为空时,单击“提交”按钮,会出现4-10出现的提示,并且表单不能提交。

图4-10 表单不会提交

只有在用户名里输入内容后,才能提交表单。可见preventDefaul()方法能阻止表单的提交行为。

如果想同时对事件对象停止冒泡和默认行为,可以在事件处理函数中返回false。这是对事件对象上同时调用stoprapagation和preventDefalut方法的一种简写方式。

在表中的例子中可以把

Even. preventDefalut(); //阻止默认行为

改写为 : return false;

也可以把事件中冒泡例子中的

Even. stoprapagation ();  //停止事件冒泡

改写为:return false;  

事件捕获

事件捕获和事件冒泡正好相反的两个过程,事件捕获是从最顶端往下开始触发。

还是冒泡事件的例子,其中元素的click事件会按照以下顺序捕获。

(1)<body>

(2)<div>

(3)<span>

很显然,事件捕获是从最外层元素开始,然后再到最里层元素。因此绑定的click事件,首先会传给<body>元素,然后再传给<div>元素,最后传给<span>元素。

遗憾的是,并非所有的主流浏览器都支持事件捕获,并且这个缺陷无法通过JavaScript来修复,jQuery不支持事件捕获,如果读者需要事件捕获,请直接使用原生的JavaScript。

4.1.5  事件对象的属性

jQuery在循环W3C规范的情况下,对事件对象的常用属性进行了封装,使得事件处理在各大浏览器下都可以正常运行而不需要进行浏览器类型判断。

1.event.type()方法

该方法的作用是可以获取到事件的类型。

$("a").click(function(event){

        alert(event.type);//获取事件类型

        return false;//阻止链接跳转

      });

以上代码运行后会返回:“click”。

2.event .preventDefaul()方法

在本章4.1.4小节事件冒泡中已经介绍过该方法,该方法的作用是阻止默认的事件行为。JavaScript中符合W3C规范的preventDefaul()方法在IE浏览器中却无效。jQuery对其进行了封装,使之能兼容各种浏览器。

3.event.stopPagation()方法

在本章4.1.4小节事件冒泡中已经介绍过该方法,该方法的作用是阻止事件的冒泡。JavaScript中符合W3C规范的stoppagation ()方法在IE浏览器中却无效。jQuery对其进行了封装,使之能兼容各种浏览器。

4.event.target()方法

event.target()方法的作用是获取到触发事件的元素。jQuery对其封装后,避免了W3C、IE和safari浏览器不同标准的差异

$("a[href=http://google.com]").click(function(event){

        alert(event.target.href);//获取触发事件的<a>元素的href属性值

        return false;//阻止链接跳转

                    });

})

以上代码运行后会返回:“http://google.com“

5.event.relatedTarget()方法

在标准DOM中,mouseover和mouseout所发生的元素可以通过event.taget()方法来访问,相关元素是通过event.relatedTarget()方法访问的。event.relatedTarget()方法在mouseover中相当于IE浏览器的event.fromElement()方法,在mouseout中相当于IE浏览器的event.toElement方法,jQuery对其进行了封装,使之能兼容各种浏览器。

6.event.pageX() 方法/event. pageY()方法

该方法的作用是获得光标相对于页面的x坐标和y坐标。如果没有使用jQuery时,那么IE浏览器中是用event.x()/event.y()方法,而在Firefox浏览器中是用event.pageX()/event.pageY()方法。如果页面上有滚动条,则还要加上滚动条的高度或宽度。在IE浏览器中还应该减去默认的2px的边框

$("a").click(function(event) {

        alert("Current mouse position: " +event.pageX + ", " + event.pageY );//获取鼠标当前相对于页面的坐标

        return false;//阻止链接跳转

      });

7.event.which()方法

该方法的作用是在鼠标点击事件中获取到鼠标的左、中、右键;在键盘事件中获取键盘的按键。

$(function(){

      $("body").mousedown(function(e){

             alert(e.which)  // 1 = 鼠标左键 left; 2 = 鼠标中键; 3 = 鼠标右键

      })

})

以上代码加载到页面后,用鼠标单击页面时,单击左、中、右键分别返回1、2、3。

8.event.metaKey()方法

针对不同浏览器对键盘中<ctrl>按键解释不同,jQuery也进行了封装,并规定event.metaKey()方法为键盘事件中获取<ctrl>按键

9.event.originaEvent()方法

该方法作用是指向原始的事件对象。

4.1.6  移除事件

可以为同一个元素绑定多个事件,也可以为多个元素绑定同一个事件。假设网页上有一个<button>元素,使用以下代码为该元素绑定多个相同的事件。

<scripttype="text/javascript">

      $(function(){

         $('#btn').bind("click",function(){

                                   $('#test').append("<p>我的绑定函数1</p>");

                      }).bind("click", function(){

                                   $('#test').append("<p>我的绑定函数2</p>");

                      }).bind("click", function(){

                                 $('#test').append("<p>我的绑定函数3</p>");

                   });

      })

</script>

 <button id="btn">点击我</button>

<div id="test"></div>

当单击按钮后,会出现图4-11所示的效果

图4-11绑定3个处理函数

1.移除按钮元素上以前注册的事件

首先在网页上添加一个移除事件的按钮。

<button id=”delAll”>删除所有事件</button>

然后为按钮绑定一个事件,jQuery代码如下:

$('#delAll').click(function(){

//处理函数

});

最后需要为该事件编写处理函数用于删除函数的所有click事件,jQuery代码如下:

      $('#delAll').click(function(){

                     $('#btn').unbind("click");

         });

因为元素绑定的都是click事件所以不写函数也可以达到相同的目的,jQuery代码如下:

      $('#delAll').click(function(){

                      $('#btn').unbind();

         });

下面来看看unbind()方法的语法构造:

      unbind([type][  , data ]);

第1个参数是事件类型,第二个参数是将要移除的函数,具体说明如下。

(1)如果没有函数,则删除所有绑定的事件。

(2)如果提供了事件类型作为参数,则只删除该类型的绑定事件。

(3)如果把绑定时处理的函数作为第2个参数,则只有这个特定的处理函数会被删除。

2.移除<Button>元素的其中一个事件

首先需要这些匿名处理函数指定一个变量。

例如下面的jQuery代码:

$(function(){

         $('#btn').bind("click", myFun1 =function(){

                                   $('#test').append("<p>我的绑定函数1</p>");

                      }).bind("click", myFun2 =function(){

                                   $('#test').append("<p>我的绑定函数2</p>");

                      }).bind("click", myFun3 =function(){

                                 $('#test').append("<p>我的绑定函数3</p>");

                   });

然后就可以单独删除某一个事件了,jQuery代码如下:

$('#delTwo').click(function(){

             $('#btn').unbind("click",myFun2);//删除“绑定函数2“

      });

当单击“删除第二个事件“按钮后,再次单击“点击我”按钮,显示图4-12的效果。

图4-12 第二个函数已经被删除

另外,对于只需要触发一次,随后就要立即解除绑定的情况,jQuery提供了一种简写的方法——one()方法。One()方法可以为元素绑定处理函数。当处理函数触发一次后,立即被删除。即在每个对象上,事件处理函数只会被执行一次。

One()方法的结构与bind()方法类似,使用方法也与bind()方法相同,其语法结构如下:

One( type, [data], fn);

示例代码如下:

<scripttype="text/javascript">

      $(function(){

         $('#btn').one("click", function(){

                                   $('#test').append("<p>我的绑定函数1</p>");

                      }).one("click", function(){

                                   $('#test').append("<p>我的绑定函数2</p>");

                      }).one("click", function(){

                                 $('#test').append("<p>我的绑定函数3</p>");

                   });

      })

</script>

<button id="btn">点击我</button>

<div id="test"></div>

使用one()方法为<button>元素绑定单击事件后,只在用户第1次单击按钮时,处理函数才执行,之后的单击毫无作用。

4.1.7  模拟操作

1.常用模拟

以上的例子都是用户必须通过单击按钮,才能触发click事件,但是有时,需要模拟用户操作,来达到单击的效果。例如在用户进入页面后,就触发click事件,而不需要用户去主动单击。

在jQuery中,可以使用trigger()方法完成模拟操作。例如可以使用下面的代码来触发id为btn的按钮的click事件。

             $('#btn').trigger("click");

这样,当页面装载完毕后,就会立即输出想要的效果,如图4-13所示。

图4-13  模拟操作

也可以直接用简化写法click(),来达到相同的效果

$('#btn').click();

2.触发自定义事件

trigger()方法不仅能触发浏览器支持的具有相同名称的事件,也可以触发自定义名称的事件。例如为元素绑定一个“myClick“的事件,jQuery代码如下:

$('#btn').bind("myClick",function(){

     $('#test').append("<p>我的自定义事件.</p>");

});

想要触发这个事件,可以使用以下代码来实现:

      $('#btn').trigger("myClick");

实现效果如图 4-14所示。


图4-14 触发自定义事件

图4-15 传递数据


3.传递数据

Trigger(type [,data])方法有两个参数,第一个参数是触发的事件类型,在第二参数是要传给事件处理函数的附加数据,以数组形式传递。通常可以通过传递一个参数给回调函数来区别这次事件是代码触发的还是用户触发的。

下面是传递数据的例子:

$('#btn').bind("myClick",function(event, message1, message2){

              $('#test').append("<p>"+message1 + message2 +"</p>");

      })

      $(‘#btn’).trigger("myClick",["我的自定义","事件"]);//传递两个数据

4.执行默认操作

trigger()方法触发事件后,会执行浏览器默认操作。例如:

      $(“input”).trigger(“focus”);

以上代码不仅会触发为<input>元素绑定的foucs事件,也会使<input>元素本身得到焦点(这是浏览器的默认操作)。

如果只想触发绑定的foucs事件,而不想执行浏览器默认操作,可以使用jQuery中另一个类似的方法——triggerHandler(“foucs”);

       $(“input”).triggerHandler(“focus”);

该方法会触发<input>元素上绑定的特定事件,同时取消浏览器对此事件的默认操作,即文本框只触发绑定的focus事件,不会得到焦点。

4.1.8  其他方法

前面已经对bind()方法进行了介绍,bind()方法不仅能为元素绑定浏览器支持的具有相同名称的事件,也可以绑定自定义事件。不仅如此,bind()方法还能做很多的事情。

1.绑定多个事件类型

例如可以为元素一次性绑定多个事件类型,jQuery代码如下:

$(function(){

    $("div").bind("mouseover mouseout", function(){

       $(this).toggleClass("over");

    });

  })

当光标滑入<div>元素时,该元素的class切换为“over”;当光标滑出<div>元素时,class切换为先前的值。这段代码等同于下面的代码:

<scripttype="text/javascript">

 $(function(){

    $("div").bind("mouseover, function(){

       $(this).toggleClass("over");

    }).bind(“mouseout”,function(){

             $(this).toggleClass("over");

});

  })

很显然,第一种方式能减少代码量,这就是jQuery提倡的“write less,do more”(写的更少,做的更多) 理念。

2.添加事件命名空间,便于管理

例如可以把为元素绑定的多个事件类型用命名空间规范起来,jQuery代码如下:

$(function(){

      $("div").bind("click.plugin",function(){

            $("body").append("<p>click事件</p>");

      });

      $("div").bind("mouseover.plugin",function(){

            $("body").append("<p>mouseover事件</p>");

      });

      $("div").bind("dblclick",function(){

               $("body").append("<p>dblclick事件</p>");

      });

      $("button").click(function(){

             $("div").unbind(".plugin"); 

      });

  });

在所绑定的事件类型后面添加命名空间,这样在删除事件时只需指定命名空间即可。单击<button>元素后,“plugin”的命名空间被删除,而不在“plugin”的命名空间的“dblclick”事件依然存在。

删除多个事件代码也可以写为以下链式代码,但显然上面的方式写得更少。

      $("div").unbind("dblclick”).unbind(“mouseover”);

3.相同的事件名称,不同命名空间执行方法

例如可以为元素绑定相同的事件类型,然后以命名空间的不同按需调用,jQuery代码如下:

      $(function(){

             $("div").bind("click",function(){

            $("body").append("<p>click事件</p>");

             });

             $("div").bind("click.plugin",function(){

            $("body").append("<p>click.plugin事件</p>");

             });

             $("button").click(function(){

              $("div").trigger("click!");    // 注意click后面的感叹号

             });

  })

当单<div>元素时后,会同时触发click事件和click.plugin事件。如果只是单击<button>元素,则只会触发click事件,而不触发click.plugin事件。注意,trigger(“click!”)后面的感叹号的作用是匹配所有不包含在命名空间的click方法。

如果需要两者都被触发,该为如下代码即可:

$("div").trigger("click");//去掉叹号

到此,jQuery的事件已经介绍完了。下面介绍jQuery中的动画。

4.2 jQuery中的动画

动画效果也是jQuery库吸引人的地方。通过jQuery的动画方法,能够轻松地为网页添加非常精彩的视觉效果,给用户一个全新的体验。

4.2.1  show()方法和hide()方法

1.show()方法和hide()方法

show()方法和hide()方法是jQuery中最基本的动画方法。在HTML文档里,为一个元素调用hide()方法,会将该元素的display样式改为“none“。

例如,使用如下代码隐藏element元素。

      $(“element”).hide();    //通过hide()方法隐藏元素

这段代码的功能与css()方法设置display属性效果相同:

element.css(“display”,”none”);   //通过css()方法隐藏元素

当把元素隐藏后,可以使用show()方法将元素的display样式设置为先前的显示的状态  (“block”或“inline”或其他除了“none”之外的值)。

jQuery代码如下:

$(“element”).show();

在前面的例子中,已经多次使用hide()方法和show()方法,通过这两种方法可以控制“内容”的显示和隐藏。

jQuery代码如下:

$(function(){

    $("#panelh5.head").toggle(function(){

      $(this).next("div.content").hide();

  },function(){

       $(this).next("div.content").show();

  })

})

注意hide()方法在将“内容”的display属性值设置为“none”之前,会记住原先的display属性值(“block”或“inline”或其他除了“none”之外的值)。当调用show()方法时,就会根据hide()方法记住的display属性值来显示元素。

在本例中,“内容”的display属性的值“block”,当单击“标题” 链接执行hide()方法的时候,hide()方法会做两步动作,首先会记住“内容”的display属性值“block”,然后把display属性值设置为“none”。

当执行show()方法的时候,“内容”的display属性的值就会被还原为调用hide()方法前的状态。

jQuery中的事件和动画:

注意:用jQuery做动画效果要求要在标准模式下,否则可能会引起动画抖动。标准模式即要求文件头部包含如下DTD定义:

<!DOCTYPE html PUBLIC "-//W3C//DTDXHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

2.show()方法和hide()方法让元素动起来

show()方法和hide()方法在不带任何参数的情况下,相当于css(“display”,”none/block/inline”),作用是立即隐藏或显示匹配的元素,不会有任何动画。如果希望在调用show()方法时,元素慢慢的显示出来,可以在show()方法指定一个速度参数,例如,指定一个速度关键字“show”。jQuery代码如下:

      $(“element”).show(“slow");

运行该代码后,元素将在600毫秒内慢慢地显示出来。其他的元素关键字还有“normal“和”fast“(长度分别是400毫秒和200毫秒);

不仅如此,还可以为显示速度指定一个数字,单位是毫秒。

例如,使用如下代码使元素在1秒钟(1000)毫秒内显示出来:

    $(“element”).show(1000);

类似的,以下代码使元素在1秒钟(1000)毫秒内隐藏:

    $(“element”).hide(1000);

在前面的例子中,把其中的hide()方法改为hide(600),show()方法改为show(600)。

JQuery代码如下:

$(function(){

    $("#panelh5.head").toggle(function(){

         $(this).next("div.content").hide(600);

     },function(){

         $(this).next("div.content").show(600);

     })

})

运行该代码后,当单击“标题“链接时,“内容” 已经产生动画了。效果4-16所示。

从代码执行过程中,可以发现,hide(600)方法会减少“内容”的高度、宽度和不透明度,直至这3个属性的值都为0,最后设置该元素 的css规则为”display:none”。同理,show(600)方法则会从上到下增加“内容”的高度,从左到右增大“内容”的宽度,同时增加“内容”的不透明度,直至新闻内容完全显示。

       

图4-16hide(“slow”)方法执行效果过程

4.2.2 fadeln()方法和发的fadeOut()方法

与show()方法不相同的是,fadeln()方法和fadeOut()方法只改变元素的不透明度。fadeOut()方法会在指定的一段时间内降低元素的不透明度,直到元素完全消失(“display:none”)。 fadeIn()方法则相反。

在上个例子中,如果只想改变“内容”的不透明度,而不想改变高度和宽度,就可以使用fadeOut()方法。

jQuery代码如下:

$("#panelh5.head").toggle(function(){

          $(this).next("div.content").fadeOut();

      },function(){

           $(this).next("div.content").fadeIn();

      })

当第1次单击“标题”链接后,“内容”慢慢地消失了(淡出),当再次单击“标题” 链接后,“内容”又慢慢地显示了(淡入),效果如图4-17所示。

图4-17 段落元素淡化效果

4.2.3  slideUp()方法和slideDown()方法

slideUp()方法和slideDown()方法只会改变元素的高度。  如果一个元素的display属性值为“none”,当调用slideDown()方法时,这个元素将由上至下延伸显示。slideUp()方法正好相反,元素将由下至上缩短隐藏。使用slideUp()方法和slideDown()方法再次对“内容”的显示和隐藏方式进行改变,代码如下:

$("#panelh5.head").toggle(function(){

         $(this).next("div.content").slideUp();

     },function(){

         $(this).next("div.content").slideDown();

     });

实现效果如图4-18所示。

图4-18 “内容”正在向下展开显示

注意:jQuery中的任何动画效果,都可以指定3种速度参数,即“slow”、“normal” 和“fast” (时间长度分别是0.6秒、0.4秒和0.2秒)。当使用速度关键字时要加引号,例如show(“slow”),如果用数字作为时间参数时就不需要加引号,例如show(1000)。

4.2.4  自定义动画方法abimate()

前面已经讲了3种类型的动画。其中show()方法和hide()方法会同时修改元素的多样式属性,即高度、宽度和不透明度;fadeOut()方法和fadeIn()方法只会修改元素的不透明度;slideUp()方法和slideDown()方法只会改变元素的高度。

许多情况下,这些方法无法满足用户的各种需求,那么就需要对动画有更多的控制,需要采用一些高级的自定义动画来解决这些问题。在jQuery中可以使用animate()方法来定义动画。其语法结构为:

  animate(params,speed,callback);

参数说明如下。

(1)  params:一个包含样式属性及值的映射,比如{property1:“value1”,property2:“value2”,…}。

(2)speed:速度参数,可选。

(3)callback:在动画完成时执行的函数,可选。

1.自定义简单动画

前面的几个例子,从不同的方面使元素动了起来,animate()方法也可以使元素动起来,而animate()方法更具有灵活性。通过animate()方法,能够实现更加精致新颖的动画效果。

首先来看一个简单的例子,有一个空白的HTML文档,里面有一个id=“panel”的<div>元素被单击后,能在页面上横向飘动。

先给这个<div>元素添加css样式。

#panel {

position: relative;

 width: 100px;

 height:100px;

border: 1px    solid #0050D0;

background: #96E555;

cursor: pointer

}

此时页面的初始化效果如图4-19所示。

图4-19 网页初始化效果

为了使这个元素动起来,要更改元素的“left”样式属性。需要注意的是在使用animate()方法之前,为了能影响该元素的 “top”、“left”、“bottom”和“right”样式属性,必须先把元素的position样式设置为“relative”或者“absolute”。本例中,设置的是“position:relative”,有了这个值,就可以调整元素的“left”属性,使元素动起来。

现在,添加如下jQuery代码:

$(function(){

   $("#panel").click(function(){

        $(this).animate({left: "500px"},3000);

     })

})

在本段代码中,首先为id为“panel”的元素创建一个单击事件,然后对元素加入animate()方法,使元素在3秒(3000毫秒)内,向右移动500像素。运动效果4-20所示。

图4-20  <div>元素右移500像素

2.累加、累减动画

在之前的代码中,设置了{left:“500px”}作为动画参数。如果在500px之前加上“+=”或者“- =”符号即表示在当前位置累加或者累减。代码如下:

$(function(){

   $("#panel").click(function(){

          $(this).animate({left:"+=500px"}, 3000);    //在当前位置累加500px

      });

});

3.多重动画

(1)同时执行多个动画

在上面的例子中,通过控制属性left的值实现了动画的效果,这是一个很单一的动画。如果同时执行多个动画,例如在元素向右滑动的同时,放大元素的高度,根据animate()方法的语法结构,可以写出如下的jQuery代码:

$(function(){

$("#panel").click(function(){

         $(this).animate({left:"500px",height:"200px"}, 3000);

     })

})

运行代码后,<div>元素在向右移动的同时,也会放大高度。

(2)  按顺序执行多个动画

上例子中,两个动画效果(left:"500px"和height:"200px")事同时发生的,如果想要按顺序执行动画,例如让<div>元素先向右滑动,然后在放大它的高度,只需把代码拆开,然后按照顺序写就可以了,jQuery代码如下:

  $(this).animate({left: "500px"}, 3000);

      $(this).animate({height:"200px"}, 3000);

因为animate()方法都是对同一个jQuery对象操作,所以也可以改为链式的写法,代码如下:

    $(this).animate({left: "500px"},3000) .animate({height: "200px"}, 3000);

这样一来,就满足上文提出的需求了。在“left”这个定位属性改变之前,“hight”属性将不会被改变。像这样,动画效果的执行具有先后顺序,称为“动画队列”。

4.综合动画

接下来将完成更复杂的动画。单击<div>元素后让它向右移动的同时增大它的高度,并将它的不透明度从50%变换到100%,然后再让它从上到下移动,同时它的宽度变大,当完成这些效果后,让它以淡出的方式隐藏。

实现这些功能的jQuery代码如下:

$(function(){

      $("#panel").css("opacity", "0.5");//设置不透明度

     $("#panel").click(function(){

         $(this).animate({left: "400px", height:"200px",opacity: "1"}, 3000)

                                   .animate({top: "200px" , width:"200px"}, 3000 )

                                   .fadeOut(“slow”);

             });

         });

运行代码后,动画效果一步步执行完毕。通过这个例子可以看出,为同一元素应用多重效果时,可以通过链式方式对这些效果进行排队。

4.2.5  动画回调函数

在上例中,如果想在最后一步切换元素的CSS样式,而不是隐藏元素:                   css("border","5px  solid blue”);

如果只是按照常规的方式,将fadeOut(“slow”)改为css(“border”,”5px solid blue”)并不能得到预期效果。预期的效果是在动画的最后一步改变元素的样式,而实际的效果是,刚开始执行动画的时候,css()方法就被执行了。出现这个问题的原因是css()方法并不会加入到动画队列中,而是立即执行。可以使用回调函数(callback)对非动画方法实现排队。只要把css()方法写在最后一个动画的回调函数里即可。代码如下:

       $("#panel").click(function(){

         $(this).animate({left: "400px", height:"200px",opacity: "1"}, 3000)

                           .animate({top:"200px" , width :"200px"}, 3000 ,function(){

                           $(this).css("border","5pxsolid blue");

             })                                                                                                                });

这样一来,css()方法就加入到动画队列中了,从而满足了上文提出的要求。

4.2.6  停止动画和判断是否处于动画状态

1.停止元素的动画

很多时候需要停止匹配元素正在进行的动画,例如上例的动画,如果需要在某处停止动画,需要使用stop()方法。stop()方法的语法结构为:

      stop([clearQueue][,gotoEnd]);

参数clearQueue和gotoEnd都是可选的参数,为Boolean值(true或false)。clearQueue代表是否要清空未执行完的动画队列,gotoEnd代表是否直接将正在执行的动画跳转到末状态。

如果直接使用stop()方法则会立即停止当前正在进行的动画,如果接下来还有动画等待继续进行,则以当前状态开始接下来的动画。经常会遇到这种情况,在为一个元素绑定hover事件之后,用户把光标移入元素时会触发动画效果,而当这个动画还没结束时,用户就将光标移出这个元素了,那么光标移除的动画效果将会被放进队列之中,等待光标移入的动画结束后再执行。因此如果光标移入移除得过快就会导致动画效果与光标的动作不一致。此时在光标的移入、移除动画之前加入stop()方法,就能解决这个问题。Stop()方法会结束当前正在进行的动画,并立即执行队列中的下一个动画。以下就可以解决刚才的问题。

      $("#panel").hover(function(){

             $(this).stop().animate({height: "150",width : "300"} , 200 );

            },function(){

               $(this).stop().animate({height :"22",width : "60" } , 300 );

        });

如果遇到组合动画,例如:

      $("#panel").hover(function(){

             $(this).stop() .animate({height : "150" } , 200 )   //如果在此时触发了光标移除的事件,将执行下面的动画, 而非光标移除事件中的动画

                 .animate({width : "300" } , 300 );

             },function(){

             $(this).stop()

                     .animate({height : "22" } , 200 )

                     .animate({width : "60" } , 300 )

      });

此时只用一个不带参数的stop()方法就显得力不从心了。因为stop()方法只会停止正在进行的动画,如果动画正执行在第1阶段(改变height的阶段),则触发光标移除事件后,只会停止当前的动画,并继续执行下面的animate({width:“300”},300)动画,而光标移除事件中的动画要等这个动画结束后才会继续执行,这显然不是预期的结果。这种情况下stop()方法的第1个参数就发挥作用了,可以把第1个参数(clearQueue)设置为true,此时程序会把当前元素接下来尚未执行完的动画队列都清空。把上面的代码改成如下代码,就能实现预期的效果。

      $("#panel").hover(function(){

                    $(this).stop(true) .animate({height : "150" } , 200 )   //如果在此时触发了光标移出事件,直接跳过后面的动画队列

                   .animate({width :"300" } , 300 )

             },function(){

                           $(this).stop(true)

                                  .animate({height: "22" } , 200 )

                                  .animate({width: "60" } , 300 )

      });

第2个参数(gotoEnd)可以用于让正在执行的动画直接到达结束时刻的状态,通常用于后一个动画需要基于前一个动画的末状态的情况,可以通过stop(false,true)这种方式来让当前动画直接到达末状态。

当然也可以两者结合起来使用stop(true,true),即停止当前动画并直接到达当前动画的末状态,并清空动画队列。

注意,jQuery只能设置正在执行的动画的最末状态,而没有提供直接到达未执行动画队列最终状态的方法。例如有一组动画:

      $(“div.content”)

             .animate({width:"300”}, 200 )

             .animate({height:"150”}, 300 )

             .animate({opacity:”0.2”},2000)

无论怎么设置stop()方法,均无法在改变“width”或者“height”时,将此<div>元素的末状态变成300*150的大小,并且设置透明度为0.2

2.判断元素是否处于动画状态

在使用animate()方法的时候,要避免动画积累而导致的动画与用户的行为不一致。当用户快速在某个元素上执行animate()动画时,就会出现动画积累。解决方法是判断元素是否正处于动画状态,如果元素不处于动画状态,才为元素添加新的动画,否则不添加。代码如下:

      If(!$(element).is(“:animated”)){       //判断元素是否正处于动画状态

             //如果当前没有进行动画,则添加动画

      }

这个判断方法在animate()动画中经常被用到,需要特别注意。

4.2.7  其他动画方法

除了上面提到的动画方法,jQuery中还有3个专门用于交互的动画方法

·toggle(speed,[callback])。

·slideToggle(speed,[callback])。

·fadeTo(speed,opacity,[callback])。

1.toggle()方法     

toggle()方法可以切换元素的可见状态。如果元素是可见的,则切换为隐藏的;如果元素是隐藏的,则切换为可见的。

给“内容”添加toggle()事件,代码如下:

        $(“#panel h5.head”).click(function(){

             $(this).next(“div.content”).toggle();

});

当单击“标题”链接后,“内容”会在可见和隐藏两种状态之间切换。

相当于以下代码:

$(“panel h5.head”).toggle(function(){

     $(this).next(“div.content”).hide();

},function(){

     $(this).next(“div.content”).show();

});

2.slideToggle()方法

slideToggle()方法通过高度变化来切换匹配元素的可见性。这个动画效果只调整元素的高度。给“内容”添加slideToggle()事件,代码如下:

$(“#panel h5.head”).click(function(){

         $(this).next(“div.content”).slideToggle();

});

当单击“标题”链接后,“内容”会在可见和隐藏两种状态之间切换,不过是通过改变元素的高度来实现的。

相当于以下jQuery代码:

$(“#panel h5.head”).toggle(function(){

             $(this).next(“div.content”).slideUp();

},function(){

      $(this).next(“div.content”).slideDown();

});

3.fadeTo()方法

fadeTo()方法可以把元素的不透明度以渐进方式调整到指定的值。这个动画只调整元素的不透明度,即匹配的元素的高度和宽带不会发生变化。

给“内容”添加fadeTo()事件,代码如下:

$(“#panel h5.head”).click(function(){

            $(this).next(“div.content”).fadeTo(600,0.2);

});

当“标题”链接被单击后,“内容”会渐渐地调整到指定的不透明度(20%)。

4.2.8  动画方法概括

从基本动画方法hide()和show()到fadeIn和fadeOut(),然后到slideUp()和slideDown(),再到自定义动画方法animate(),最后到交互动画方法toggle()、slideToggle()和fadeTo()。在介绍了如此多的动画方法后,现总结概括如下。

1.改变样式属性

表4-1 动画方法说明

方法名

说明

hide()和show()

同时修改多个样式属性即高度、宽度和不透明度

fadeIn()和fadeOut()

只改变不透明度

slideUp()和slideDown()

只改变高度

fadeTo()

只改变不透明度

toggle()

用来代替hide()方法和show()方法,所以会同时修改多个样式属性即高度、宽度和不透明度

slideToggle()

用来代替slideUp()方法和slideDown()方法,所以只能改变高度

animate()

属于自定义动画的方法,以上各种动画方法实质内部都调用了animate()方法。此外,直接使用animate()方法还能自定义其他的样式属性,例如:“left”、“marginLeft”、“scrollTop”等

需要特别注意animate()方法,可以使用它来替代其它所有的动画方法。

·用animate()方法代替show()方法:

$(“p”).animate({height:”show”,waidth:”show”,opacity:”show”},400);                       等价于:$(“p”).show(400);

·用animate()方法代替fadeIn()方法:

$(“p”).animate({opacity:”show”},400);

等价于:$(“p”).fadeIn(400);

·用animate()方法代替slideDown()方法:

$(“p”).animate({height:”show” },400);

     等价于:$(“p”).slideDown(400);

·  用animate()方法代替fadeTo()方法

$(“p”).animate({opacity:”0.6”},400);

     等价于:$(“p”).fadeTo(400,0.6);

事实上,这些动画就是animate()方法的一种内置了特定样式属性的简写形式。在animate()方法中,这些特定样式的属性值可以为“show”、“hide”和“toggle”,也可以是自定义数字(值)。

2.动画队列

(1)一组元素上的动画效果

·当在一个animate()方法中应用多个属性时,动画是同时发生的。

·当以链式的写法应用动画方法时,动画时按照顺序发生的。

(2)多组元素上的动画效果

·默认情况下,动画都是同时发生的。

·当以回调的形式应用动画方式时,动画是按照回调顺序发生的。

另外,在动画方法中,要注意其他非动画方法会插队,例如 css()方法要使非动画方法也按照顺序执行,需要把这些方法写在动画方法的回调函数中。

4.3 视频展示效果实例

下面通过制作某视频网的视频展示效果,使读者对jQuery的事件和动画效果有一个更为全面的了解。

在模拟这个效果之前,需要明确哪些是必须要做的。

(1) 当视频展示内容处于最后一个版面的时候,如果再向后,则应该跳转到第1个版面。

(2) 当视频展示内容处于第1个版面的时候,如果再向前,就应该跳转到最后一个版面。

(3) 左上角的箭头旁边的蓝色圆点应该与动画一起切换,它代表着当前所处的版面。

理清思路后,就可以开始动手制作这个效果。

首先把页面结构设计好,可以把HTML结构简化成如下形式:

<div class=”v_show”>

         <div class=”v_caption”>

                //头部标题,按钮等

         </div>

         <div class=”v_content”>

                //视频内容展示区域

         </div>

</div>

最终实际页面的HTML代码如下:

<div class=”v_show”>

  <div class=”v_caption”>

                <h2 class=”cartoon” title=”卡通动漫”>卡通动漫</h2>

                <divclass=”highlight_tip”>

<span class=”current”>1</span><span>2</span><span>3</span><span>4</span>

                </div>

         <divclass=”change_btn”>

                <span class=”prev”>上一页</span>

                <span class=”next”>下一页</span>

</div>

                <em><ahref=”#”>更多>></a></em>

  </div>

  <div class=”v_content”>

         <divclass=”v_content_list”>

         <ul>

                <li><ahref=”#”><img src=”img/01.jpg” alt=”海贼王”/></a><h4><a href=”#”>海贼王</a></h4><span>播放:<em>28,276</em></span></li>

                             [..中间的li元素省略…]

              <li><ahref=”#”><img src=”img/04.jpg” alt=”龙珠”/></a><h4><a href=”#”>龙珠</a></h4><span>播放<em>57,865</em></span></li>

                       <ul>

                </div>

         </div>

  </div>

为页面的HTML代码应用CSS后,初始化页面如图4-21所示。

图4-21 初始化页面

接下来的工作是按照需求编写脚本,来控制页面的交互性。

首先通过jQuery选择器获取向右的箭头元素,然后为他绑定click事件。

因为“向右箭头”和“视频展示区域”在同一个祖先元素下,所以可以通过“向右箭头”来找到“视频展示区域”。首先获取“向右箭头”的祖先元素,然后在祖先元素下寻找“视频展示区域”。

jQuery代码如下:

$(“span.next”).click(function()){    //绑定click事件

var $parent = $(this).parents(“div.v_show”);//根据当前单击的元素获取到父元素

var $v_show = $parent.find(“div. v_content_list”);//找到“视频内容展示区域”

var $v_content = $parent.find(“div. v_content”);//找到“视频内容展示区域”外围的div

      })

找到相应的元素之后,就可以给相应的元素添加动画效果了。可以通过使用animate()方法控制“视频展示区域”的left样式属性的值来达到动画效果。很容易就可以获得left的值,left的值就等于每个版面的宽度。

可以使用width()方法来获取每个版面的宽度,代码如下:

  var v_width = $v_content.width(); //获取区域内容的宽度,带单位

完成这一步后,此时的代码如下:

$("span.next").click(function(){    //绑定click事件

           var $parent = $(this).parents("div.v_show");//根据当前单击元素获取到父元素

              var $v_show =$parent.find("div.v_content_list"); //找到“视频内容展示区域”

              var $v_content =$parent.find("div.v_content");

                                 //找到“视频内容展示区域”外围的div元素

              var v_width = $v_content.width() ;

if(当动画到最后一版面){

            $v_show.animate({left : '0px'}, "normal");

                                       //通过改变left值,跳转到第1个版面

            }else{

                   $v_show.animate({left : '-='+v_width }, "normal");

                         //改变left值,达到每次换一个版面

            }

});

现在的问题是如何知道动画已经到达最后一版。

“视频展示区域”每个版面摆放了4张视频图片,如果能够获取到视频图片的总数,然后用总数除以4就可以得到总的版面数。例如总共有8张视频图片,那么就是2个版面;如果有12张视频图片,那么就是3个版面;如果只有9张视频图片,则必须把小数向上舍入,即3个版面。在还没有到达最后一个版面之前,需要在当前版面数的基础上加1,当到达最后一个版面时(即当前的版面数等于总的版面数),则需要把当前的版面数设置为1,使之重新开始动画效果。

(1) 首先初始化当前的版面数为1,即第1个版面:

var  page=1;

然后根据刚才的分析,写出如下代码:

var page = 1;

var i = 4; //每版放4个图片

   $("span.next").click(function(){    //绑定click事件

          var $parent =$(this).parents("div.v_show");//根据当前单击元素获取到父元素

             var$v_show = $parent.find("div.v_content_list"); //找到“视频内容展示区域”

             var$v_content = $parent.find("div.v_content");

 //找到“视频内容展示区域”外围的DIV元素

             varv_width = $v_content.width() ;

             varlen = $v_show.find("li").length;       //总的视频图片数

             varpage_count = Math.ceil(len / i) ;   //只要不是整数,就往大的方向取最小的整数

             if(page == page_count ){ 

//已经到最后一个版面了,如果再向后,必须跳转到第一个版面。

             $v_show.animate({left : '0px'}, "slow"); //通过改变left值,跳转到第1个版面

             page= 1;

      }else{

             $v_show.animate({left : '-='+v_width }, "slow"); //改变left值,达到每次换一个版面

             page++;

             }

});

这一步完成后,还需要使左上角的箭头旁边的蓝色远点跟随动画一起切换,来标识当前所处的版面。只是要把样式“current”添加到代表当前版面的“蓝色圆点”上就可以了。

如果想知道当前的版面数,方法很简单,其实前面的代码已经完成了这个任务,变量page的值就是版面数。由于eg()方法的下标是从0开始,因此只要把page减去1就可以得到当前的版面数,然后使用下面的代码来标识当前版面:

$parent.find("span").eq((page-1)).addClass("current").siblings().removeClass("current");//给指定的span元素添加current样式,然后去掉span元素的同辈元素上的current样式

此时,把代码整合,如下所示:

      varpage = 1;

      varI = 4;                                                                      //每张放4张图片

      //”向右”按钮

      $("span.next").click(function(){                                //绑定click事件

             var$parent = $(this).parents("div.v_show");//根据当前单击元素获取到父元素

             var$v_show = $parent.find("div.v_content_list"); //寻找到“视频内容展示区域”

             var$v_content = $parent.find("div.v_content");

 //寻找“视频内容展示区域”外围的div

             varv_width = $v_content.width() ;

             varlen = $v_show.find("li").length;       //总的视频图片数

             varpage_count = Math.ceil(len / i) ;   //只要不是整数,就往大的方向取最小的整数

             if(page == page_count ){

//已经到最后一个版面了,如果再向后,必须跳转到第1个版面。

$v_show.animate({ left:’0px’}, ”slow”)};

                                         //通过改变left值,跳转到第1个版面

page = 1;

             }else{

$v_show.animate ({ left : ‘-=’+v_width },“slow”);

//改变left值,达到每次换一个版面

page++;

}

$parent.find(“span”).eq((page-1)).addClass(“current”).siblings().removeClass(“current”)

});

运行上面的代码,慢慢地单击向右按钮,并没有发现任何问题,但是如果快速的单击“向右”按钮,就会出现问题了:放开光标,图片还在移动。

在前面已经介绍过动画队列,这里的问题就是由动画队列引起的。当快速单击“向右”按钮时,单击产生的动画会追加到动画队列中,从而出现放开光标之后,图片还在继续滚动的情况。

为了解决这个问题,可以在动画方法外围加一段判断元素是否处于动画状态的代码,如下所示:

if(!$v_show.is(":animated")){//判断”视频内容展示区域”是否正在处于动画

如果不处于动画,则给它添加下一个动画。

最终的jQuery代码如下:

      $(function(){

             varpage = 1;

             varI = 4;                                                                      //每张放4张图片

             $("span.next").click(function(){                                //绑定click事件

                    var$parent = $(this).parents("div.v_show");//根据当前单击元素获取到父元素

                    var$v_show = $parent.find("div.v_content_list"); //寻找到“视频内容展示区域”

var $v_content =$parent.find("div.v_content");

//寻找“视频内容展示区域”外围的div

                    varv_width = $v_content.width() ;

                    varlen = $v_show.find("li").length;

                    varpage_count = Math.ceil(len / i) ;

     //只要不是整数,就往大的方向取最小的整数

                    if(!$v_show.is(":animated") ){   

//判断“视频内容展示区域”是否正在处于动画

//已经到最后一个版面了,如果再向后,必须跳转到第1个版面

                           if(page == page_count ){

$v_show.animate({left:’0px’}, ”slow”)};

                                         //改变left值,跳转到第1个版面

page = 1;

                           }else{

                                  //通过改变left值,达到每次换一个版面

$v_show.animate({ left : ‘-=’+v_width }, “slow”);

page++;

}

                    }

$parent.find(“span”).eq((page-1)).addClass(“current”)

.siblings().removeClass(“current”)

      });

运行代码后,单击“向右”按钮,效果一切正常。此时已经把“向右”按钮的交互效果完成了。“向左”按钮的交互代码与“向右”按钮类似,区别是在当前的版面数已经为第1版时,如果再往前,则需要把版面跳转到最后一个版面,操作代码如下:

      if(!$v_show.is(":animated") ){           //判断“视频内容展示区域”是否正在处于动画

             if(page == page_count ){       //已经到第1个版面了,如果再向前,必须跳转到最后一个版面

                    $v_show.animate({ left : ‘-=’+v_width*(page_count-1)}, “slow”);

                    page= page_count;

             }else{

$v_show.animate({ left : ‘+=’+v_width}, “slow”);}

Page--;

                    }

      }

此时,效果就完成了,“向右”和“向左”按钮都可以单击,动画效果也能正常运行,并且当前版面也能被标识。效果如图4-22所示。

图4-22 动画效果

五、 jQuery对表单、表格的操作及更多应用

通过前面4章的介绍和学习,读者已经对jQuery比较熟悉了,本章将通过讲解jQuery在表单(Form)和表格(Table)中的应用来加深对jQuery的理解。表单和表格都是HTML的重要组成部分,分别用于采集、提交用户输入的信息和显示列表数据。通过本章的实战锻炼,相信读者的jQuery技能又有一个极大的提高。

5.1 表单应用

一个表单有3个基本组成部分。

(1)表单标签:包含处理表单数据所用的服务端程序URL以及数据提交到服务器的方法。

(2)表单域:包含文本框、密码框、隐藏域、多行文本框、复选框、单选框、下拉选择框和文件上传框等。

(3)表单按钮:包含提交按钮、复位按钮和一般按钮,用于将数据传送到服务器上或者取消传送,还可以用来控制其他定义了处理脚本的处理工作。

本节主要讲解jQuery在表单域中的应用。

5.1.1  单行文本框应用

文本框是表单域中最基本的元素,基于文本框的应用有很多。此时只简单介绍其中的一个应用——获取和失去焦点改变样式。

首先,在网页中创建一个表单,HTML代码如下:

      <formaction=”#” method=”POST” id=”regForm”>

             <fieldset>

                    <legend>个人基本信息</legend>

                    <div>

                           <labelfor=”username”>名称:</lable>

<inputid="username" type="text" />

                    </div>

         <div>

                           <labelfor="pass">密码:</label>

                           <inputid="pass" type="password" />

                    </div>

         <div>

                           <labelfor="msg">详细信息:</label>

                           <textareaid="msg" rows="2" cols="20"></textarea>

                    </div>

             </fieldset>

      </form>

应用样式后,初始化网页效果如图5-1所示。

图5-1 初始化网页效果

当文本框获取焦点后,它的颜色需要有变化,当它失去焦点后,则要恢复为原来样式。此功能可以极大地提升用户体验,使用户的操作可以得到及时的反馈。

首先在CSS中添加一个类名为focus的样式。

CSS代码如下:

.focus {

       border: 1px solid #f00;

       background: #fcc;

}

然后为文本框添加获取和失去焦点事件。

jQuery代码如下:

$(function(){

             $(":input").focus(function(){

$(this).addClass("focus");

      }).blur(function(){

             $(this).removeClass("focus");

      });

})

当文本框获得焦点时,会出现图5-2所示的效果。

图5-2 文本框获取焦点

5.1.2  多行文本框应用

1.   高度变化

首先创建一个表单,其中包含评论框,HTML代码如下:

<form>

<divclass="msg">

             <divclass="msg_caption">

                    <spanclass="bigger" >放大</span>

                    <spanclass="smaller" >缩小</span>

             </div>

             <div>

             <textareaid="comment" rows="8" cols="20">多行文本框高度变化.多行文本框高度变化.多行文本框高度变化.多行文本框高度变化.多行文本框高度变化.多行文本框高度变化.多行文本框高度变化.多行文本框高度变化.多行文本框高度变化.</textarea>

             </div>

</div>

</form>

然后思考以下两种情况:

(1)当点击“放大”按钮后,如果评论框的高度小于500px,则在原有的高度的基础上增加50px。

(2)当点击“缩小”按钮后,如果评论框的高度大于50px,则在原有的高度的基础上减去50px。

图5-3 初始化页面效果

JQuery代码如下:

      $(function(){

          var $comment = $('#comment');  //获取评论框

          $('.bigger').click(function(){ //放大按钮绑定单击事件

                      if( $comment.height() < 500 ){

                              $comment.height( $comment.height() + 50 );//重新设置高度,在原有的基础上加50

                      }

             })

             $('.smaller').click(function(){//缩小按钮绑定单击事件

                           if($comment.height() > 50 ){

                                  $comment.height($comment.height() - 50 ); //重新设置高度,在原有的基础上减50

                           }

             });

      });

当点击“放大”或“缩小”按钮后,评论框就有了相应的变化,但此时评论框的变化效果很呆板,缺乏缓冲效果。在动画章节里,讲解过自定义动画方法animate(),此处可以将其中的一段代码:

$comment.heigth(comment.height()+50);

改为$comment.animate({height:”+=50”},400);

因此当点击“放大”按钮后,评论框的高度会在0.4秒内将增大50px。

注意在动画的过程中,需要判断评论框是否正处于动画,如果处于动画过程中,则不追加其他动画,以免造成动画队列不必要的累积,使效果出现问题。

最终的jQuery 代码如下:

      $(function(){

          var $comment = $('#comment');  //获取评论框

          $('.bigger').click(function(){ //放大按钮绑定单击事件

                if(!$comment.is(":animated")){ //判断是否处于动画

                      if( $comment.height() < 500 ){

                                $comment.animate({height : "+=50" },400); //重新设置高度,在原有的基础上加50

                      }

                    }

             })

             $('.smaller').click(function(){//缩小按钮绑定单击事件

                if(!$comment.is(":animated")){//判断是否处于动画

                           if($comment.height() > 50 ){

                                  $comment.animate({height : "-=50" },400); //重新设置高度,在原有的基础上减50

                           }

                    }

             });

      });

此时评论框的高度变化具有一定的缓冲效果,比直接用heigth()方法的效果好多了。

2.滚动条高度的变化。

在多行文本框中,还有另外一个应用,就是通过控制多行文本框的滚动条的变化,使文本框的内容滚动。

与控制高度的方法相同,只不过此处需要控制的是另一个属性,即scrollTop,将以上代码改成如下:

      $(function(){

          var $comment = $('#comment');  //获取评论框

          $('.up').click(function(){ //”向上”按钮绑定单击事件

                if(!$comment.is(":animated")){ //判断是否处于动画

                                $comment.animate({scrollTop:"-=50" },400);

                      }

                    }

             })

             $('.down').click(function(){//“向下”按钮绑定单击事件

                if(!$comment.is(":animated")){

                                  $comment.animate({scrollTop:"+=50" },400);                                       }

                    }

             });

      });                                             

当点击“向上”或“向下”按钮时,评论框的滚动条就会滚动到指定的位置,效果如图5-4所示。

图5-4 通过控制scrollTop,使内容滚动

5.1.3  复选框应用

对复选框基本的应用,就是对复选框进行全选、反选和全不选等操作。复杂的操作需要与选项挂钩,来达到各种级联反映效果。

首先在空白的网页中创建一个表单,其中放入一组复选框,HTML代码如下:

<form method="post"action="">

   你爱好的运动是?

  <br/>

   <input type="checkbox" name="items" value="足球"/>足球

      <inputtype="checkbox" name="items" value="篮球"/>篮球

      <inputtype="checkbox" name="items" value="羽毛球"/>羽毛球

      <inputtype="checkbox" name="items" value="乒乓球"/>乒乓球

  <br/>

   <input type="button" id="CheckedAll" value="全 选"/>

   <input type="button" id="CheckedNo" value="全不选"/>

    <input type="button"id="CheckedRev" value="反 选"/>

       <input type="button"id="send" value="提 交"/>

</form>

如果需要使复选框处于选中或者不选状态,必须通过控制元素的checked属性来达到目的。如果属性checked的值为true,说明被选中;如果值为false,说明没被选中。因此可以基于这个属性来完成需求。

全选操作就是当用户单击“全选”按钮时,需要将复选框组全部选中。此时,需要为“全选”按钮绑定单击事件,然后使用选择符寻找符合要求的复选框,最后通过arrt()方法来设置属性checked的值,使之选中。JQuery代码如下:

$("#CheckedAll").click(function(){

           $('[name=items]:checkbox').attr('checked',true);

       });

全不选操作,只需要将复选框的checked的属性的值设置为false,就可以实现,jQuery代码如下:

$("#CheckedNo").click(function(){

          $('[type=checkbox]:checkbox').attr('checked',false);

       });

反选操作稍微有些复杂,需要循环每个复选框进行设置,取它们值的反值,即如果是true,就设置为false;如果是false,就设置为true,此种情况下可以使用非运算符“!”。

使用下面的代码来实现反选操作:

$("#CheckedRev").click(function(){

               $('[name=items]:checkbox').each(function(){

                                         //$(this).attr("checked",!$(this).attr("checked"));

                                         this.checked=!this.checked;

               });

       }

复选框被选中后,用户单击“提交”按钮,需要将选中的项的值输出。可以通过val()方法获取选中的值。JQuery代码如下:

$("#send").click(function(){

             varstr="你选中的是:\r\n";

             $('[name=items]:checkbox:checked').each(function(){

                    str+=$(this).val()+"\r\n";

             })

             alert(str);

      });

  })

单击“提交“按钮后,显示效果如图5-5所示。

图5-5 选中输出

此处不用按钮来控制复选框的全选与全不选,而用另一个复选框来控制,将按钮代码用一个复选框来代替,HTML代码如下:

<form>

你爱好的运动是?<input type="checkbox"id="CheckedAll" />全选/全不选<br/>

   <input type="checkbox" name="items" value="足球"/>足球

      <inputtype="checkbox" name="items" value="篮球"/>篮球

      <inputtype="checkbox" name="items" value="羽毛球"/>羽毛球         

      <inputtype="checkbox" name="items" value="乒乓球"/>乒乓球<br/>

      <inputtype="button" id="send" value="提 交"/>

</form>

首先需要对另一个复选框控制,根据前面的功能代码,可以写下面的代码:

$("#CheckedAll").click(function(){

                    if(this.checked){                       //如果当前点击的多选框被选中

                           $('input[type=checkbox][name=items]').attr("checked",true );

                    }else{                                                     

                       $('input[type=checkbox][name=items]').attr("checked", false );

                    }

       });

进一步观察思考后发现,所有复选框的checked属性的值和控制全选的复选框的checked属性的值是相同的,因此可以省略if判断,直接赋值,代码如下:

$("#CheckedAll").click(function(){

                    //所有checkbox跟着全选的checkbox走。

                    $('[name=items]:checkbox').attr("checked",this.checked );

       });

当点击id为“CheckedAll“的复选框后,复选框组将被选中。当在复选框组里取消某一个选项的选中状态时,id为“CheckedAll“的复选框并没有被取消选中状态,而此时需要它和复选框组能够联系起来,即复选框组里如果有一个或者更多没选中时,则取消id为“CheckedAll“的复选框的选中状态;如果复选框组都被选中时,则id为“CheckedAll“的复选框也自动被选中。

因此需要对复选框组进行操作,已通过他们来控制id为“CheckedAll“的复选框。具体实现思路如下。

(1)对复选框组绑定单击事件。

(2)定义一个flag变量,默认为true。

(3)循环复选框组,当没有被选中的项时,则把变量flag的值设置为false。

(4)根据变量flag的值来设置id为“CheckedAll“的复选框是否选中。

1如果flag为true,说明复选框组被选中。

2如果flag为false,说明复选框组至少有一个被选中。

根据以上思路,可以写出如下jQuery代码:

      $('[name=items]:checkbox').click(function(){

     var flag =true;

     $(‘[name=items]’:checkbox).each(function(){

    If(!this.checked)

{

flag=false;

}

});

$('#CheckedAll').attr('checked',flag);

});

此时id为“CheckedAll“的复选框和复选框组就可以连动起来了,如图5-6所示。

图5-6 复选框和复选框组相互影响

除了上述的思路外,也可以用下面的思路来实现。

(1)对复选框组绑定单击事件。

(2)判断复选框的总数是否与选中的复选框数量相等。

(3)如果相等,则说明全选中了,id为“CheckedAll”的复选框应当处于选中状态,否则不选中。

根据提供的思路,可以写出如下的jQuery代码:

      $('[name=items]:checkbox').click(function(){

                    //定义一个临时变量,避免重复使用同一个选择器选择页面中的元素,提升程序效率。

             var$tmp=$('[name=items]:checkbox');

                    //用filter方法筛选出选中的复选框。并直接给CheckedAll赋值。             $('#CheckedAll').attr('checked',$tmp.length==$tmp.filter(':checked').length);

});

5.1.4  下拉框应用

下拉框有非常多的应用,这里也只选择其中的一个常用、典型的应用来进行介绍。

首先在网页中增加一左一右两个下拉框,然后将它们下方分别加上几个功能按钮。

HTML代码如下:

<div class="centent">

      <selectmultiple="multiple" id="select1"style="width:100px;height:160px;">

                    <optionvalue="1">选项1</option>

                    <optionvalue="2">选项2</option>

                    <optionvalue="3">选项3</option>

                    <optionvalue="4">选项4</option>

                    <optionvalue="5">选项5</option>

                    <optionvalue="6">选项6</option>

                    <optionvalue="7">选项7</option>

      </select>

             <div>

             <spanid="add" >选中添加到右边&gt;&gt;</span>

                    <spanid="add_all" >全部添加到右边&gt;&gt;</span>

             </div>

      </div>

<div class="centent">

<select multiple="multiple"id="select2" style="width: 100px;height:160px;">

                    <optionvalue="8">选项8</option>

             </select>

             <div>

                    <spanid="remove">&lt;&lt;选中删除到左边</span>

                    <spanid="remove_all">&lt;&lt;全部删除到左边</span>

             </div>

      </div>

初始化后,网页效果如图5-7所示。

图5-7 初始化效果

需要实现的功能如下:

(1)将选中的选项添加给对方。

(2)将全部选项添加给对方。

(3)双击某个选项将其添加给对方。

首先实现第一个功能,即将下拉列表中的选项添加给对方。

首先要获取下拉列表中被选中的选项,然后将当前下拉列表中选中的选项删除,最后将删除的选项添加给对方。

假设先将左边的选项添加到右边。JQuery代码如下:

$(“#add”).click(function(){

      var$options=$(“#select1 option:selected”);//获取选中的选项

      var#remove=$options.remove();                 //删除下拉列表中选中的选项

      $remove.appendTo(“#select2”);                  //追加给对方

});

在前面的章节提到过,删除和追加这两个步骤可以用appendTo()方法直接完成,因此可以将上面的代码简化如下:

$(‘#add’).click(function){

      var$options = $(“#select1 option:selected”);//获取选项中的选项

      $options.appendTo(“#select2”);//追加对方

}

然后实现第二个功能,即将全部的选项添加给对方。

将全部的选项添加给对方和将选中的选项添加给对方之间的唯一区别就是获取的对象不同,因此只要稍微修改代码就可以实现,jQuery代码如下:

$(‘#add-all’).click(function(){

      var$options = $(“#select1 option”);//获取选项中的选项

      $options.appendTo(‘#select2’);

});

然后实现第三个功能,即双击某个选项将其添加给对方。

首先给下拉列表绑定双击事件。

JQuery代码如下:

      $(‘#select1’ ) . ( dblclick ( function(){

             //绑定双击事件   将选中的选项添加给对方

});

然后可以通过$(“option:selected”,this)方法来获取被选中的选项,这样就可以完成第三个功能了,jQuery代码如下:

      $('#select1').dblclick(function(){//绑定双击事件

var $options =$(“option:selected”,this);//获取选项中的选项

      $options.appendTo('#select2');//追加给对方

      });

前面三个功能都是将左边的选项添加给右边,如果要将右边的选项添加给左边,代码也是完全相同,此处不再多说。最终效果如图5-8所示:

图5-8 最终效果

5.1.5  表单验证

表单作为HTML最重要的一个组成部分,几乎在每个网页上都有体现,例如用户提交信息、用户反馈信息和用户查询信息等,因此它是网站管理者与浏览者之间沟通的桥梁。在表单中,表单验证的作用也是非常重要的,它能使表单更加灵活,美观和丰富。

以一个简单的用户注册为例。首先新建一个新的表单,HTML代码如下:

<form method="post"action="">

      <divclass="int">

             <labelfor="username">用户名:</label>

             <inputtype="text" id="username" class="required" />

      </div>

      <divclass="int">

             <labelfor="email">邮箱:</label>

             <inputtype="text" id="email" class="required" />

      </div>

      <divclass="int">

             <labelfor="personinfo">个人资料:</label>

             <inputtype="text" id="personinfo" />

      </div>

      <divclass="sub">

             <inputtype="submit" value="提交" id="send"/><input type="reset"id="res"/>

      </div>

</form>

显示效果如图5-19所示。

在表单内class属性为“required”的文本框是必须填写的,因此需要将它与其他的非必须填写表单元素加以区分,即在文本框后面追加一个红色的小星星标识。可以使用append()方法来完成,代码如下:

$("form:input.required").each(function(){

                    var$required = $("<strong class='high'> *</strong>"); //创建元素

                    $(this).parent().append($required);//然后将它追加到文档中

             });

显示效果如图5-10所示。

图5-9 表单初始化

图5-10 红色小星星标识

当用户在“用户名”文本框中填写完信息后,将光标的焦点从“用户名”移除时,需要即时判断用户名是否符合验证规则。当光标的焦点从“邮箱”文本框移除时,需要即时判断“邮箱”填写是否正确,因此需要给表单元素添加失去焦点事件,即blur。JQuery代码如下:

$('form :input').blur(function(){  // 为表单元素添加失去焦点事件

})

验证表单元素步骤如下。

(1)判断当前失去焦点的元素是“用户名”还是“邮箱”,然后分别处理。

(2)如果是“用户名”,判断元素的值的长度是否小于6,如果小于6,则用红色提醒用户输入不正确,反之,则用绿色提醒用户输入正确。

(3)如果是“邮箱”,判断元素的值是否符合邮箱的格式,如果不符合,则用红色提醒用户输入不正确,反之,则用绿色提醒用户输入正确。

(4)将提醒信息追加到当前元素的父元素的最后。

根据以上分析,可以写出如下jQuery代码:

$('form :input').blur(function(){  // 为表单元素添加失去焦点事件

      var$parent = $(this).parent();

      //验证用户名

      if($(this).is('#username') ){

             if(this.value=="" || this.value.length    <6  ){

                    varerrorMsg = '请输入至少6位的用户名.';

      $parent.append("<spanclass="formtips onError">'+errorMsg+'</span>');

                                  }else{

                                         varokMsg = '输入正确.';

      $parent.append('<spanclass="formtips onSuccess">'+okMsg+'</span>');

                                  }

                     }                                      

                     //验证邮件

      if($(this).is('#email') ){

if(this.value==""||(this.value!=""&& !/.+@.+\.[a-zA-Z]{2,4}$/.test(this.value) ) ){

                                    var errorMsg = '请输入正确的E-Mail地址.';

      $parent.append('<spanclass="formtips onError">'+errorMsg+'</span>');

      }else{

                                    var okMsg = '输入正确.';

      $parent.append('<spanclass="formtips onSuccess">'+okMsg+'</span>');

                           }

                     }

             })

})

当连续几次输入错误的格式后,会出现图5-11所示的效果。

图5-11 操作多次的提示效果

由于每次在元素失去焦点后,都会创建一个新的提醒元素,然后将它追加到文档中,最后就出现了多次的提醒信息。因此,需要在创建提醒元素之前,将当前元素以前的提醒元素都删除。可以使用remove()方法来完成,代码如下:

$('form :input').blur(function(){  // 为表单元素添加失去焦点事件

                     var $parent = $(this).parent();

                     $parent.find(".formtips").remove();//去掉先前的提醒

                     })

显示效果如图5-17所示。

图5-12 正确效果

当鼠标在表单元素中多次失去焦点时,都可以提醒用户填写是否正确。但是,如果用户无视错误提醒,执意要单击“提交”按钮时,为了使表单填写准确,在表单提交之前,需要对表单的必须填写元素进行一次整体的验证,可以直接用trigger()方法来触发blur事件,从而达到验证的效果。如果填写错误,就会以红色提醒用户;如果用户名和邮箱都不符合规则,那么就有两处错误,即有两个class为“onError”的元素,因此可以根据class为“onError”元素的长度来判断是否可以提交。如果长度为0,即true,说明已经可以提交了;如果长度大于0,即false,说明有错误,需要阻止表单提交。阻止表单提交可以直接用“return  false”语句。

根据以上分析,可以在提交事件中写出如下jQuery代码:

$('#send').click(function(){

                           $("form:input.required").trigger('blur');

                           varnumError = $('form .onError').length;

                           if(numError){

                                  returnfalse;

                           }

                           alert("注册成功,密码已发到你的邮箱,请查收.");

              });

显示效果如图5-13所示。

图5-13 正确提交

用户也许会提出:为什么每次都要等字段元素失去焦点后,才提醒输入是否正确?如果输入时就可以提醒,这样就可以更加即时了。

为了达到用户提出的要求,需要给表单元素绑定keyup事件和focus事件,keyup事件能在用户每次松开按键时触发,也可以实现即时提醒。代码如下:

$(“form :input”).blur(function(){

      //失去焦点处理函数

//代码省略…

}).keyup(function(){

      $(this).triggerHandle(“blur”);

}).focus(function(){

      $(this).triggerHandler(“blur”);

});

这样当用户将光标定位到文本框上和改变文本框的值时,表单就会即时提醒用户填写是否正确,从而符合了用户的需求。

在前面的章节已经提过,trigger(“blur”)不仅会触发为元素绑定的blur事件,也会触发浏览器默认的blur事件,即不能将光标定位到文本框上。而triggerHandler(“blur”)只会触发为元素绑定的blur事件,而不触发浏览器的默认的blur事件。

至此,表单的验证过程就全部完成。读者可以根据自己的实际需求修改验证规则。

注意:客户端的验证仅用于提升用户操作体验,而服务端仍需对用户输入的数据合法性进行校验,对于禁用了脚本的用户和用户自制的网页提交操作,必须在服务端验证。

5.2 表格应用

在CSS技术之前,网页的布局基本都是表格制作,当有了CSS之后,表格就被很多设计师抛弃。但笔者认为,在进行网页布局时不能盲目的抛弃表格,在该用表格时候,还要用表格。例如数据列表,用表格来显示非常适合。

下面以表格中几个常见的应用作为示例来讲解。

5.2.1  表格变色

例如一张人员资料表,其HTML代码如下:

<table>

             <thead>

                    <tr><th>姓名</th><th>性别</th><th>暂住地</th></tr>

             </thead>

             <tbody>

                    <tr><td>张山</td><td>男</td><td>浙江宁波</td></tr>

                    <tr><td>李四</td><td>女</td><td>浙江杭州</td></tr>

                    <tr><td>王五</td><td>男</td><td>湖南长沙</td></tr>

                    <tr><td>赵六</td><td>男</td><td>浙江温州</td></tr>

                    <tr><td>Rain</td><td>男</td><td>浙江杭州</td></tr>

                    <tr><td>MAXMAN</td><td>女</td><td>浙江杭州</td></tr>

             </tbody>

      </table>

应用样式后,显示效果如图5-14所示。

图5-14 初始化效果

这是一张非常普通的表格,现在需要给表格进行隔行变色操作。

1.普通的隔行变色

首先定义两个样式。

Css代码如下:

.even{background:#FFF38F;}  /* 偶数行样式*/

.odd{ background:#FFFFEE;}  /* 奇数行样式*/

然后选择表格奇数行 和偶数行分别添加样式,可以使用选择器来完成,代码如下:

$(function(){

             $("tr:odd").addClass("odd");  /* 奇数行添加样式*/

             $("tr:even").addClass("even");/* 偶数行添加样式*/

      })

效果如图5-15所示。

注意:$(“tr:odd”)和$(“tr:even”)选择器中索引是从0 开始的,因此第一行始偶数行。

上面的代码会将表头也算进去,因此需要排除表格头部<thead>中的<tr>,将选择符改成如下代码:

$(function(){

             $("tbody>tr:odd").addClass("odd");//先排除第一行,然后给奇数行添加样式

             $("tbody>tr:even").addClass("even");//先排除第一行,然后给偶数行添加样式

      })

显示效果如图5-16所示。


图5-15 普通的隔行变色

图5-16 表格隔行变色


如果还需要将某一行变为高亮显示状态,那么可以使用contains选择起来实现。例如“王五”这行,代码如下:

$("tr:contains('王五')").addClass("selected");

效果如图5-17所示。

图5-17 高亮显示“王五”这行

2.单选框控制表格行亮度

在以上表格的基础上,在第一列前加上一列单选框,如图5-18所示:

图5-18 带单选框的表格

当单击某一行后,此行被选中高亮显示,并且单选框被选中。实现该过程需要以下几个步骤。

(1)为表格行添加单击事件。

(2)给单击的当前行添加高亮样式,然后将他的兄弟行的高亮样式去掉,最后将当前行里的单选框设置为选中。

根据分析,可以写出如下jQuery代码:

$('tbody>tr').click(function() {

                    $(this).addClass('selected')

                           .siblings().removeClass('selected')

                           .end().find(':radio').attr('checked',true);

             });

这样,就可以通过单击每行来实现表格行高亮,同时此行所在的单选框也被选中。

上面代码中使用了end()方法,当前对象是$(this), 当前行addClass(“selected”)操作时,对象并未发生变化,当执行siblings().removeClass(“selected”)操作时,对象已经变为$(this).siblings(),因此后面的操作都是针对这个对象的,如果需要重新返回到$(this)对象,就可以使用end()方法,这样后面的

.find(':radio').attr('checked',true);

操作就是:

$(this).find(':radio').attr('checked',true);

而不是:

$(this).siblings().find(':radio').attr('checked',true);

另外,初始化表格的时候,如果默认已经以有单选框被选中,那么也需要处理,代码如下:

$('table:radio:checked').parent().parent().addClass('selected');

这样 当初始化表格的时候,默认已经选中的行将被高亮显示,如图5-19所示。

图5-19 默认选中行被高亮显示

注意:$('table:radio:checked').parent().parent().addClass('selected');是通过parent()方法逐步向父节点获取相应的元素的,也可以使用parent()方法直接获取:

$('table:radio:checked').parent(“tr”).addClass('selected');

此外,如果通过has选择器也可以进一步简化,表示含有选中的单选框的<tr>行将被高亮显示:

$(‘tbody>tr:has(:checked)’).addClass(‘selected’);

3.复选框控制表格行高亮

复选框控制表格行与单选框不同,复选框能选择多行变色,并没有限制被选择的个数。当单击某行时,如果已经高亮了,则移除高亮样式并去掉当前行复选框的选中状态;如果还没有亮,则添加高亮样式并将当前行的复选框选中。

判断是否已经高亮,可以使用hasClass()方法来完成。JQuery代码如下:

$('tbody>tr').click(function() {

                    if($(this).hasClass('selected')) {

                           $(this).removeClass('selected')

                                  .find(':checkbox').attr('checked',false);

                    }else{

                           $(this).addClass('selected')

                                  .find(':checkbox').attr('checked',true);

                    }

             });

显示效果如图5-20所示。

图5-20 复选框控制行高亮

此外,在不改变设计思路的前提下,上面的代码还可以再简化成如下代码:

             $('tbody>tr').click(function(){

                    //判断当前是否选中

var hasSelected=$(this).hasClass('selected');

                    //如果选中,则移出selected类,否则就加上selected类

                    $(this)[hasSelected?"removeClass":"addClass"]('selected')

                           //查找内部的checkbox,设置对应的属性。

                           .find(':checkbox').attr('checked',!hasSelected);

             });

当用户刚进入页面时,也要处理已经被选中的表格行。jQuery代码如下:

$('tbody>tr:has(:checked)').addClass('selected');

5.2.1  表格展开关闭

在上例的人员表格的基础上,增加人员分类。

HTML代码如下:

      <table>

             <thead>

                    <tr><th>姓名</th><th>性别</th><th>暂住地</th></tr>

             </thead>

             <tbody>

                    <trclass="parent" id="row_01"><tdcolspan="3">前台设计组</td></tr>

                    <trclass="child_row_01"><td>张山</td><td>男</td><td>浙江宁波</td></tr>

                    <trclass="child_row_01"><td>李四</td><td>女</td><td>浙江杭州</td></tr>

                    <trclass="parent" id="row_02"><tdcolspan="3">前台开发组</td></tr>

<trclass="child_row_02"><td>王五</td><td>男</td><td>湖南长沙</td></tr>

                    <trclass="child_row_02"><td>找六</td><td>男</td><td>浙江温州</td></tr>

                    <trclass="parent" id="row_03"><tdcolspan="3">后台开发组</td></tr>

                    <trclass="child_row_03"><td>Rain</td><td>男</td><td>浙江杭州</td></tr>

                    <trclass="child_row_03"><td>MAXMAN</td><td>女</td><td>浙江杭州</td></tr>

             </tbody>

      </table>

显示效果如图5-21所示。

图5-21 人员分类

现在需要实现的是当单击分类行是,可以关闭相应的内容。例如单击“前台设计组”行,则它对应的“张山和李四”两行将收缩。

在这个表格中,给每个<tr>元素设置属性是非常重要的,读者可以在HTML代码中看出一些规则,即给分类行设置了class=“parent”属性,同时也分别给它们设置了id值,而在它们下面的行,只设置了class属性,并且这个class的值是在id值的基础上通过加上 “child_”来设置的。基于以上规则,jQuery实现代码如下:

$(function(){

      $('tr.parent').click(function(){   // 获取所谓的父行

                    $(this).toggleClass("selected")   // 添加/删除高亮

                           .siblings('.child_'+this.id).toggle();  // 隐藏/显示所谓的子行

      });

})

运行代码后,当单击表格的父行后,相应的子行会收缩,如图5-22所示。

图5-22 单击某行,对应的子行会收缩

5.2.3  表格内容筛选

在下面的例子中,如果要高亮显示”王五”那一行,可以使用contains选择器来完成,代码如下:

$(“tr:contains(‘王五’)”).addclass(“selected”);

  //选择器contains,能匹配包含指定文本的元素

利用该选择器再结合jQuery的filter()筛选方法,可以实现表格内容的过滤。

例如使用下面的jQuery代码就可以筛选出含有文本“李”的表格行。

     $("table tbody tr").hide().filter(":contains(李)").show();

显示效果如图5-23所示。

图5-23 筛选之后效果

首先在表格上方添加一个文本框,用于根据用户输入的内容来筛选表格内容,然后为文本框绑定keyup事件,代码如下:

$(function(){

      $("#filterName").keyup(function(){

           //…

         })

  })

 最后将flter(":contains(李)")代码中的“李”用变量值代替,代码如下:

  $(function(){

      $("#filterName").keyup(function(){

            $("table tbody tr")

                                  .hide()

                                  .filter(":contains('"+($(this).val() )+"')")

                                  .show();

         })

  })

当在文本框中输入“王”时,就会筛选出相应的表格行,显示效果如图5-24所示。

注意表单元素有个特点,就是刷新网页后,其值会保持不变。例如在刚才筛选操作后,刷新网页,则会出现图5-25所示的现象,表单元素的值还存在,但表格内容已经被刷新了。

图5-24 根据用户输入的文本来筛选

图5-25 刷新后显示的表格数据

要解决这个问题,只需要在DOM刚加载完时,为表单元素绑定事件并且立即触发该事件即可。

$(function(){

      $("#filterName").keyup(function(){

            $("table tbody tr")

                                  .hide()

                                  .filter(":contains('"+($(this).val() )+"')")

                                  .show();

         }).keyup();

  })

这样,当页面被刷新后,就会立即执行id为"#filterName"的keyup事件,因此表格内容就会保持刚才筛选出来的结果。

5.3 其他应用

5.3.1  网页字体大小

在某些网站经常有“放大”和“缩小”字号的控制按钮,通过单击它们,可以使网页的文字呈现不同的大小。

首先在空白的网页上添加两个字号控制按钮和一些文字,HTML代码如下:

<div class="msg">

      <divclass="msg_caption">

             <spanclass="bigger" >放大</span>

             <spanclass="smaller" >缩小</span>

      </div>

      <div>

             <pid="para" >

             Thisis some text. This is some text. This is some text. This is some text. This issome text. This is some text. This is some text. This is some text. This issome text. This is some text. This is some text. This is some text. This issome text.This is some text. This is some text. This is some text. This is sometext. This    is some text. This is sometext.

             </p>

      </div>

</div>

显示效果如图5-26所示。

表5-26 网页初始化效果

当单击这两个按钮时可以分别控制文本字体的放大和缩小。因此,需要对“放大”按钮和“缩小”按钮进行相应的处理,代码如下:

$(function(){

             $("span").click(function(){

                    varthisEle = $("#para").css("font-size");

                    vartextFontSize = parseFloat(thisEle , 10);

                    varunit = thisEle.slice(-2); //获取单位

                    varcName = $(this).attr("class");

                    if(cName== "bigger"){

                                  textFontSize+= 2;

                    }elseif(cName == "smaller"){

                                  textFontSize-= 2;

                    }

                    $("#para").css("font-size",  textFontSize + unit );

             });

      });

下面详细讲解以上代码所完成的操作。

$(function(){

             $("span").click(function(){

                    //…

             });

      });

当文档加载完毕后,为所有的<span>元素绑定单击事件。

var thisEle =$("#para").css("font-size");

var textFontSize = parseFloat(thisEle ,10);

获取id为“para”的元素的字体大小。获取的值是将返回的数字和单位,即16px。然后使用parseFloat()方法去掉单位,因此16px就变成了16。 parseFloat()方法的第2个参数表示进制,代码表示的是10进制。

var unit = thisEle.slice(-2);

上面这段代码是获取单位,slice()方法返回字符串中从指定的字符开始的一个子字符串。因为这里使用的度量单位px是两个字符,所以指定字符串应该从倒数第2个字符开始。在后面再次设置字体大小是,就可以直接把单位拼接上。

var cName =$(this).attr("class");

                    if(cName== "bigger"){

                                  textFontSize+= 2;

                    }elseif(cName == "smaller"){

                                  textFontSize-= 2;

                    }

If语句用于判断当前被单击的<span>元素的class是否为“bigger”。如果是“bigger”,则需要为字体变量 (textFontSize) 增加 2px。如果单击的是 “smaller”,则要为字体变量(textFontSize) 减掉2px。

textFontSize +=2;的写法等价于textFontSize =textFontSize +2;

$("#para").css("font-size",  textFontSize + unit );

最后,再次获取“pava”元素并为它的font-size属性赋予新的值  (textFontSize ),并且一定要拼接上单位。

如果发现无限放大和缩小不太合适,可以判断一下最小字体和最大字体,代码如下:

//…省略代码

if(cName == "bigger"){

                              if( textFontSize <= 22 ){

                                         textFontSize+= 2;

                                  }

                    }elseif(cName == "smaller"){

                              if( textFontSize >= 12  ){

                                         textFontSize-= 2;

                                  }

                    }

                    $("#para").css("font-size",  textFontSize + unit);

显示效果如图5-27所示。

图5-27 字体大小变化

5.3.2  网页选项卡

制作选项卡的原理比较简单,通过隐藏和显示来切换不同的内容。

与前面的例子相同,首先构建HTML结构,代码如下:

<div class="tab">

      <divclass="tab_menu">

             <ul><liclass="selected">时事</li>

                    <li>体育</li>

                    <li>娱乐</li>

             </ul>

      </div>

      <divclass="tab_box">

              <div>时事</div>

              <div class="hide">体育</div>

              <div class="hide">娱乐</div>

      </div>

</div>

应用样式后,网页呈现效果如图5-28所示。

图5-28 选项卡效果

默认是选项卡的第1个选项被选中,然后下面区域显示相应的内容。例如图5-28所示,当单击“体育”选项卡时,“体育”选项卡将处于高亮状态,同时下面的内容也切换成“体育”了。当单击“娱乐”选项卡时,也显示相应的内容。下面将详细介绍实现选项卡的过程。

首先需要为<li>元素邦定单击事件,代码如下:

var $div_li =$("div.tab_menu ulli");

          $div_li.click(function(){

                //…

             })

绑定事件后,需要将当前单击的<li>元素高亮,然后去掉其他同辈<li>元素的高亮。

$(function(){

        var $div_li =$("div.tab_menu ulli");

        $div_li.click(function(){

             $(this).addClass("selected")            //当前<li>元素高亮

             .siblings().removeClass("selected");  //去掉其它同辈<li>元素的高亮

             })

      })

单击选项卡后,当前<li>元素处于高亮状态,而其他的<li>元素已去掉了高亮状态。但选项卡下面的内容还没被切换,因此需要将下面的内容也对应切换。显示效果如图5-29所示。

从选项卡的基本结构可以知道,每个<li>元素都分别对应一个<div>区域。因此可以根据当前单击的<li>元素在所有<li>元素中的索引,然后通过索引来显示对应的区域,代码如下:

  var $div_li =$("div.tab_menu ul li");

      $div_li.click(function(){

             $(this).addClass("selected")            //当前<li>元素高亮

             .siblings().removeClass("selected");  //去掉其它同辈<li>元素的高亮

      var index = $div_li.index(this);  // 获取当前点击的<li>元素 在 全部li元素中的索引。

             $("div.tab_box> div")   //选取子节点。不选取子节点的话,会引起错误。如果里面还有div

             .eq(index).show()   //显示 <li>元素对应的<div>元素

             .siblings().hide();//隐藏其它几个同辈的<div>元素

      })

这样,当单击<li>元素后,选项卡相应的内容也将切换,效果如图5-30所示。


图5-29 内容没被切换

图5-30 对应的内容被切换


在上面的代码中,要注意$(“div.tab_box>div”)这个子选择器,如果用$(“div.tab_box div”)子选择器,当子节点里再包含<div>元素的时候,就会引起程序错乱。因此获取当前选项卡下的子节点,才是这个例子所需要的。

至此制作选项卡的过程就完成了。如果读者还想加强些效果,例如光标滑入滑出效果,可以添加hover事件,代码如下:

$(function(){

      var$div_li =$("div.tab_menu ul li");

      $div_li.click(function(){

             $(this).addClass("selected")            //当前<li>元素高亮

             .siblings().removeClass("selected");  //去掉其它同辈<li>元素的高亮

      var index = $div_li.index(this);  // 获取当前点击的<li>元素 在 全部li元素中的索引。

             $("div.tab_box> div")   //选取子节点。不选取子节点的话,会引起错误。如果里面还有div

             .eq(index).show()   //显示 <li>元素对应的<div>元素

             .siblings().hide();//隐藏其它几个同辈的<div>元素

      }).hover(function(){

             $(this).addClass("hover");

      },function(){

             $(this).removeClass("hover");

      })

})

这样当光标滑过其他选项时,选项的样式会发生变化,如图5-31所示。

图5-31 滑过“娱乐”选项

5.3.3  网页换肤

自从Web 2.0开始流行后,很多网站更加注重用户自定义,例如在网页上用户可以自定义新内容,可以任意拖动网页内容,也可以给网页选择一套自己喜欢的颜色等。

网页换肤的原理就是通过调用不同的样式表文件来实现不同皮肤的切换,并且需要将换好的皮肤记入Cookie中,这样用户下次访问时,就可以显示用户自定义的皮肤了。

首先设置HTMl的结构,在网页中添加皮肤选择按钮(<li>元素)和基本内容,代码如下:

<ul id="skin">

             <liid="skin_0" title="灰色" class="selected">灰色</li>

             <liid="skin_1" title="紫色">紫色</li>

             <liid="skin_2" title="红色">红色</li>

<li id="skin_3" title="天蓝色">天蓝色</li>

             <liid="skin_4" title="橙色">橙色</li>

             <liid="skin_5" title="淡绿色">淡绿色</li>

      </ul>

      <divid="div_side_0">

             <divid="news">

                    <h1class="title">时事新闻</h1>

             </div>

      </div>

      <divid="div_side_1">

             <divid="game">

                    <h1class="title">娱乐新闻</h1>

             </div>

      </div>

然后根据HTML代码预定义几套换肤用的样式,分别有灰色、紫色、红色等6套。默认是灰色。

在设计HTML代码时,用了一些小技巧,就是将皮肤选择器按钮<li>元素的id与网页皮肤的样式文件名称设置的相同。这样就可以使完成换肤操作简化很多。

然后为HTML代码添加样式,注意HTML结构要有一个带id的样式表链接,通过操作该连接的href属性的值,从而实现换肤。代码如下:

<link href="css/skin_0.css"rel="stylesheet" type="text/css" id="cssfile"/>

运行后网页的初始化效果如图5-32所示。

图5-32 初始化效果

最后为皮肤选择按钮添加单击事件,有如下两个步骤。

(1)当皮肤选择按钮被单击后,当前皮肤就被勾选。

(2)将网页内容换肤。

首先完成第1步,它与前面选项卡例子中高亮当前选项的代码相同,代码如下:

  var$li =$("#skin li");

$li.click(function(){

       $("#"+this.id).addClass("selected")                //当前<li>元素选中

             .siblings().removeClass("selected");  //去掉其它同辈<li>元素的选中

      })

然后完成第2步,即设置网页内容皮肤。前面为<link>元素设置的id,此时可以通过attr()方法为<link>元素的href属性设置不同的值,代码如下:

  var$li =$("#skin li");

$li.click(function(){

      $("#"+this.id).addClass("selected")                //当前<li>元素选中

             .siblings().removeClass("selected");  //去掉其它同辈<li>元素的选中

                    $("#cssfile").attr("href","css/"+this.id+".css");//设置不同皮肤

      })

完成后,当单击皮肤选择按钮时,就可以切换网页皮肤了,如图5-33所示,但是当用户刷新网页或者关闭浏览器后,皮肤又会被初始化,因此需要将当前选择的皮肤进行保存。

图5-33 单击按钮后换肤

在jQuery中有一款cookie插件,此处就将其引入,代码如下:

  <!--   引入jQuery的cookie插件 -->

      <scriptsrc="js/jquery.cookie.js" type="text/javascript"></script>

   将当前皮肤保存进Cookie后,代码如下:

    var $li =$("#skin li");

        $li.click(function(){

             $("#"+this.id).addClass("selected")         //当前<li>元素选中

             .siblings().removeClass("selected");//去掉其它同辈<li>元素的选中

             $("#cssfile").attr("href","css/"+(this.id) +".css"); //设置不同皮肤

                    $.cookie("MyCssSkin" ,  this.id , {path: '/', expires: 10 });

             });

保存进Cookie后,就可以通过Cookie来获取当前的皮肤了。如果Cookie确实存在,则将当前皮肤设置为Cookie记录的值,代码如下:

//…省略代码

      varcookie_skin = $.cookie( "MyCssSkin");

      if(cookie_skin) {

       $("#"+cookie_skin).addClass("selected")    //当前<li>元素选中

                    .siblings().removeClass("selected");//去掉其它同辈<li>元素的选中

             $("#cssfile").attr("href","css/"+cookie_skin +".css"); //设置不同皮肤

             $.cookie("MyCssSkin" ,  cookie_skin  , { path: '/', expires: 10 });

      }

//…省略代码

完成的jQuery代码如下:

$(function(){

      var$li =$("#skin li");

      $li.click(function(){

      $("#"+this.id).addClass("selected")    //当前<li>元素选中

             .siblings().removeClass("selected");  //去掉其它同辈<li>元素的选中

      $("#cssfile").attr("href","css/"+(this.id) +".css"); //设置不同皮肤

      $.cookie("MyCssSkin" ,  this.id , {path: '/', expires: 10 });

      });

      varcookie_skin = $.cookie( "MyCssSkin");

      if(cookie_skin) {

             $("#"+cookie_skin).addClass("selected")     //当前<li>元素选中

               .siblings().removeClass("selected"); //去掉其它同辈<li>元素的选中

             $("#cssfile").attr("href","css/"+cookie_skin +".css");   //设置不同皮肤

             $.cookie("MyCssSkin" ,  cookie_skin  , { path: '/', expires: 10 });

             }

      })

此时,网页换肤功能不仅能正常切换,而且也能保存到Cookie中,当用户刷新网页后,仍然是当前选择的皮肤。

在Click事件中的函数内容与if(cookie_skin){}内的判断内容类似,只是有一个变量不同,因此可以通过给函数传递不同的参数,这样就可以多次调用(抽象化),代码如下:

 function switchSkin(skinName){

      $("#"+skinName).addClass("selected")    //当前<li>元素选中

             .siblings().removeClass("selected");//去掉其它同辈<li>元素的选中

      $("#cssfile").attr("href","css/"+skinName +".css"); //设置不同皮肤

      $.cookie("MyCssSkin" ,  skinName , {path: '/', expires: 10 });

      }

然后在单击事件和if(cookie_skin){}内分别调用对应的参数:

$(function(){

                    var$li =$("#skin li");

                    $li.click(function(){

                           switchSkin(this.id );

                    });

                    varcookie_skin = $.cookie( "MyCssSkin");

                    if(cookie_skin) {

                           switchSkin(cookie_skin );

                    }

             });

至此,网页换肤功能就完成了,效果如图5-34所示。

图5-34 网页换肤完成

六、    jQuery与Ajax的应用

Ajax 全称为“Asynchronous Javascript and XML”(异步JavaScript和XML),它并不是指一种单一的技术,而是有机地利用了一系列交互式网页应用相关的技术所形成的结合体。它的出现,揭开了无刷新更新页面的新时代,并有代替传统的Web方式和通过隐藏的框架来进行异步提交的趋势,是Web开发应用的一个里程碑。

6.1  Ajax的优势和不足

6.1.1  Ajax的优势

1.   不需要插件支持

Ajax不需要任何浏览器插件,就可以被绝大多数主流浏览器所支持,用户只需要允许JavaScript在浏览器上执行即可。

2.   优秀的用户体验

这是Ajax技术的最大优点,能在不刷新整个页面的前提下更新数据,这使得Web应用程序能更为迅速地回应用户的操作。

3.提高Web程序的性能

与传统模式相比,Ajax模式在性能上的最大区别就在于传输数据的方式,在传统模式中,数据提交是通过表单(Form)来实现的,而数据获取是靠全页面刷新来重新获取整页的内容。而Ajax模式只是通过XmlHttpRequest对象向服务器端提交希望提交的数据,即按需发送。

4.减轻服务器和宽带的负担

Ajax的工作原理相当于在用户和服务器之间加了一个中间层,使用户操作与服务器响应异步化。它在客户端创建Ajax引擎,把传统方式下的一些服务器负担的工作转移到客户端,便于客户端资源来处理,减轻服务器和带宽的负担。

6.1.2  Ajax的不足

世界上并没有完美的事物,同样Ajax也并不是一项非常完美的技术。Ajax主要有以下几点不足之处。

1.   浏览器对XMLHttpRequest对象的支持度不足

Ajax的不足之一首先来自于浏览器。InternetExplorer在5.0及以后的版本才支持XmlHttprequest对象(现阶段大部分客户端上的IE浏览器是IE6及以上),Mozilla、Netscape等浏览器支持xmlhttprequest则更在其后。为了使得Ajax应用能在各个浏览器中正常运行,程序员必须花费大量的精力编码以兼顾各个浏览器之间的差别,来让Ajax应用能够很好地兼容各个浏览器。这使得Ajax开发的难度比普通的Web开发高出很多,许多程序员因此对Ajax望而生畏。

2.   破坏浏览器“前进”、“后退”按钮的正常功能

在传统的网页中 ,用户经常会习惯性的使用浏览器自带的“前进”和“后退”按钮,然而Ajax改变了此web浏览习惯。在Ajax中“前进”和“后退”按钮的功能都会失效,虽然可以通过一定的方法(添加锚点)来使得用户可以使用“前进”和“后退”按钮,但相当于传统的方式却麻烦了很多,对于大多数程序员来说宁可放弃前进、后退的功能,也不愿在繁琐的逻辑中去处理该问题。然而,对于用户来说,他们经常会碰到这种情况,当单击一个按钮触发一个Ajax交互后又觉得不想这样做,接着就去习惯性地单击“后退”按钮,结果发生了最不愿意看到的结果,浏览器后退到先前的一个页面,通过Ajax交互得到的内容完全消失了。

3.   对搜索引擎的支持不足

对于搜索引擎的支持也是Ajax的一项缺憾。通常搜索引擎都是通过爬虫程序来对互联网上的数以亿计的海量数据来进行搜索整理的,然而爬虫程序现在还不能理解那些奇怪的Javascript代码和因此引起的页面内容的变化,这使得应用Ajax的站点在网络推广上相对于传统站点明显处于劣势。

4.   开发和调试工具的缺乏

JavaScript是Ajax的的重要组成部分,在目前,由于缺少很好的javaScript开发和调试工具,使很多web开发者对JavaScript望而生畏,这对于编写Ajax代码就更加困难了。同时,目前许多Web开发者已经习惯使用可视化的工具,对亲自动手编写代码有畏惧感,这也在一定程度上影响了大家对Ajax的应用。

6.2 Ajax的XMlhttpRequest对象

Ajax的核心是XMlhttpRequest对象,它是Ajax实现的关键——发送异步请求、接收响应及执行回调都是通过它来完成的。XMLHttpRequest对象最早是在Microsoft  Internet Explorer 5.0ActiveX组件中被引入的,之后各大浏览器厂商都以JavaScript内置对象的方式来实现XmlHttpRequest对象。虽然大家对它的实现方式有所区别,但绝大多数浏览器都提供了类似的属性和方法,而且在实际脚本编写方法上的区别也不大,实现得到的效果也基本相同。目前W3C组织正致力于制定一个各浏览器厂商可以统一遵照执行的XmlHttpRequest对象标准,用来推进Ajax技术的推广与发展。

6.3编写第1个Ajax例子

正式接触jQuery地Ajax操作之前,先看一个用传统的JavaScript实现的Ajax例子。例子描述:单击一个按钮,然后通过传统的JavaScript的Ajax的方式从服务器端取回一个“Hello Ajax!”的字符串并显示在页面上。

首先在前台页面中书写HTML代码,代码如下:

<input type=”button” value=”Ajax提交” οnclick=”Ajax();”/>

<div id=”resTest”><div>

<button> 按钮用来触发Ajax,id为“resText”的元素来显示从服务器返回的HTML文本。

接下来的任务就是完成Ajax()函数,实现步骤如下:

(1)  定义一个函数,通过该函数来异步获取信息,代码如下:

Function Ajax(){

//…

}

(2)  声明一个空对象用来装入XMLHttpRequest对象,代码如下:

Var xmlHttpReq=null;

(3)  给XMLHttpRequest对象赋值,代码如下:

if (window.ActiveXObject){              //IE5 IE6是以ActiveXObject的方式引入XMLHttpRequest的

             xmlHttpReq= new ActiveXObject("Microsoft.XMLHTTP");

} else if (window.XMLHttpRequest){         //除IE5 IE6 以外的浏览器XMLHttpRequest是window的子对象

             xmlHttpReq= new XMLHttpRequest();   //实例化一个XMLHttpRequest对象

      }

IE5、IE6是以ActiveXObject的方式引入XMLHttpRequest对象的,而其他浏览器的XMLHttpRequest对象是window的子对象。

(4) 实例化成功后,使用open()方法初始化XMLHttpRequest对象,指定HTTP方法和要使用的服务器URL,代码如下:

xmlHttpReq.open("GET","javascript.ashx",true);      //调用open()方法并采用异步方式

默认情况下,使用XMLHttpRequest对象发送的HTTP请求是异部进行的,但是可以显示地把async参数设置为true,如上面代码所示。

(5) 因为要做一个异步调用,所以需要注册一个XMLHttpRequest对象将调用的回调事件处理器当它的readyState只改变时调用。当readyState值被改变时,会激发一个readystatechange事件,可以使用onreadystatechange属性来注册该回调事件处理器,代码如下:

xmlHttpReq.onreadystatechange=RequestCallBack;//设置回调函数

(6) 使用send()方法发送该请求,因为这个请求使用的是HTTP的GET方式,所以可以在不指定参数或使用null参数的情况下调用send()方法,代码如下:

xmlHttpReq.send(null);    //因为使用get方式提交,所以可以使用null参调用

当请求状态改变时,XMLHttpRequest对象调用onreadystatechange属性注册的事件处理器。因此,在处理该响应之前,事件处理器应该首先检查readyState的值和HTTP状态。当请求完成加载(readyState值为4)并且响应已经成功(HTTP状态值为200)时,就可以调用一个javaScript函数来处理该响应内容,代码如下:

function RequestCallBack(){//一旦readyState值改变,将会调用这个函数

                   if(xmlHttpReq.readyState == 4){

                           if(xmlHttpReq.status== 200){

                           //将xmlHttpReq.responseText的值赋给ID为 resText 的元素

document.getElementById("resText").innerHTML=xmlHttpReq.responseText;

                           }

                   }

          }

最后,如果单击“Ajax提交”按钮后发现网页上出现了“Hellow Ajax!”,那么就完成了第一个Ajax调用。如图6-1所示。

图6-1第一个Ajax实例

以上就是实现XMLHttpRequest对象使用的所有细节,它不必将Web页面的所有内容发送到服务器,而是按需发送。使用javaScript启动一个请求并处理相应的返回值然后使用浏览器的DOM方法更新页面中的数据,显然,这种无刷新的模式能给网站带来更好的用户体验。但是XMLHttpRequest对象的很多属性和方法,对于想快速入门Ajax的人来说,似乎并不是个容易的过程。

幸运的是,jQuery提供了一些日常开发中需要的快捷操作,例如load、Ajax、get和post等等,使用jQuery开发Ajax将变得极其简单。这样开发人员就可以将程序开发集中在业务和用户体验上,而不需要理会那些繁琐的XMLHttpRequest对象。下面开始介绍jQuery中的Ajax。

6.4 jQuery中的Ajax

jQuery对Ajax操作进行了封装,在jQuery中$.ajax()方法属于最底层的方法,第2层是load()、$.get()和$.post()方法,第3层是$.getScript()和$.getJSON()方法。首先介绍第2层的方法,因为其使用率很高。

6.4.1load()方法

1.   载入HTML文档

load()方法是jQuery中最为简单和常用的Ajax方法,能载入远程HTML代码并插入DOM中。它的结构为:

load(url[,data][,callback])

Load()方法参数解释如表6-1所示。

表6-1 load()方法参数解释

参数名称

  类  型

说   明

url

String

请求HTML页面的URL地址

data(可选)

Object

发送至服务器的key/value数据

Callback(可选)

Function

请求完成时的回调函数,无论请求成功或失败

首先构建一个被load()方法加载并追加到页面中的HTML文件,名字为loadtest.htm,HTML代码如下:

<div class="comment">

   已有评论:

</div>

<div class="comment">

 <h6>张三:</h6>

 <p class="para">沙发.</p>

</div>

<div class="comment">

 <h6>李四:</h6>

 <p class="para">板凳.</p>

</div>

<div class="comment">

 <h6>王五:</h6>

 <p class="para">地板.</p>

</div>

然后新建一个空白页面,在上面添加两个元素:<button>按钮用来触发Ajax事件,id为“resText”的元素用来显示追加的HTML内容。HTML代码如下:

<input type="button"id="send" value="Ajax获取" />

<div class="comment">已有评论:</div>

<div id="resText"></div>

接下来就可以开始编写jQuery代码了。等DOM元素加载完毕后,通过单击id为send的按钮来调用load()方法,然后将loadtest.htm的内容加载到id为“resText”的元素里。

JQuery代码如下:

$(function(){

        $("#send").click(function(){

                      $("#resText").load("loadtest.htm");

        })

})

当按钮被单击后,出现如图6-2所示的界面。

显然,load()方法完成了原本很繁琐的工作。开发人员只需要使用jQuery选择器为HTML片段指定目标位置,然后将要加载的文件的URL作为参数传递给load()方法即可。当单击按钮后,loadtest.htm页面的HTML内容就会被加载并插入主页面<div id=”rexText” ></div>的元素中。

注意:loadtest.htm页面里并没有添加样式,但现在加载的内容有样式了,这些样式是在主页面中添加的,即主页面相应的样式会立即应用到新加载的内容上。

图6-2 load()方法调用成功

2.筛选载入的HTML文档

上个例子是将loadtest.htm页面中的内容都加载到id 为“resText”的元素里。如果只需要加载loadtest.htm页面内的某些元素,那么可以使用load()方法的URL 参数来达到目的。通过为URL 参数指定选择符,就可以很方便地从加载过来的HTML 文档里筛选出来所需要的内容。

load()方法的URL 参数的语法结构为:“url selector”。注意,URL 和选择器之间有个空格。

例如只需要加载 loadtest.htm 页面中 class 为“para”的内容,可以使用如下代码来完成。$("#resText").load("loadtest.htm  .para");

运行效果如图6-3所示。

图6-3 用load()方法加载一部分HTML元素

3.传递方式

load()方法的传递方式根据参数data来自动指定。如果没有参数传递,则采用 GET 方式传递;反之,则会自动转换为 POST 方式。关于 GET 和POST 传递方式的区别,将在后面进行讲解。

//无参数传递,则是GET方法

$("#resText").load(“get1.ashx” ,function(){

            //……

});

//有参数传递,则用 POST 方法

$("#resText").load("get1.ashx”,{name:”rain”, age: “22”}, function(){

      //……

});

4.回调参数

对于必须在加载完成后才能继续的操作,load()方法提供的回调函数(callback),该函数有三个参数,分别代表请求返回的内容、请求状态和XMLHttpRequest 对象,jQuery 代码如下:

$("#resText").load("loadtest.htm.para",function (responseText, textStatus, XMLHttpRequest){

//responseText: 请求返回的内容

//textStatus:请求状态:success,error,notmodified ,timeout4种

// XMLHttpRequest: XMLHttpRequest对象

});

注意 :在 load()方法中,无论Ajax请求是否成功,只要当请求完成(complete)后,回调函数(callback)就被触发,对应下面将介绍的$.ajax()方法中的complete回调函数。

6.4.2  $.get()方法和$.post()方法

Load()方法通常用来从Web 服务器上获取静态的数据文件,然而这并不能体现Ajax 的全部价值。在项目中,如果需要传递一些参数给服务器中的页面,那么可以使用$.get()方法或者$.post()方法(或者是后面要讲的$.ajax()方法)。

注意:$.get()方法和$.post()方法是jQuery中的全局函数,而在此之前讲的jQuery方法都是对jQuery对象进行操作的。

1.   $.get()方法

$.get()方法使用GET 方式来进行异步请求。

它的结构为:

$.get()(  url  [,data]  [, callback]  [, type]  )

$.get()方法参数解释如表6-2所示。

表6-2  $.get()方法参数解释

 参数名称

    类型

说明

url

String

请求的HTML页的URL地址

data(可选)

Object

发送至服务器的key/value数据会作为QueryString附加到请求URL中

callback(可选)

Function

载入成功时回调函数(只有当Response的返回状态是success才调用该方法)自动将请求结果和状态传递给该方法

Type(可选)

String

服务器返回内容的格式,包括xml、html、script、json、text和_default

下面是一个评论页面的HTML代码,通过这段代码来介绍$.get()方法的使用。

<form id="form1"action=”#”>

<p>评论:</p>

 <p>姓名: <input type="text" name="username"id="username" /></p>

 <p>内容: <textarea name="content" id="content" rows=”2” cols=”20” >

</textarea></p>

<p><input type="button"id="send" value="提交"/></p>

</form>

<div class='comment'>已有评论:</div>

<div id="resText" >

</div>

本段代码将生成图6-4所示的页面。

图6-4 评论初始化页面

将姓名和内容填写好后,就可以准备提交评论了。如图6-5所示。

图6-5 填写好数据

(1)  使用参数

首先,需要确定请求页面的URL 地址。代码如下:

$("#send").click(function(){

                    $.get("get1.ashx"    data参数,回调函数);

});

然后,在提交之前,需要获取“姓名”和“内容”的值作为data参数传递给后台, 代码如下:

$("#send").click(function(){

                    $.get("get1.ashx",{

                                         username:  $("#username").val() ,

                                         content:  $("#content").val()

},回调函数 );

});

如果服务器端接收到传递的data 数据并成功返回,那么就可以通过回调函数将返回的数据显示到页面上。

$.get()方法的回调函数只有两个参数,代码如下:

Function (data,  textStatus){

      //data  :  返回的内容,可以是XML文档、JSON文件、HTML 片段等等

//textStatus : 请求状态:success,error,notmodified.timeout 4种

}

data参数代表请求返回的内容, textStatus参数代表请求状态,而且回调函数只有当数据成功返回(success)后才被调用,这点与load()方法不一样。

(2)  数据格式

服务器上返回的格式有多种,它们都可以完成同样的任务,以下是几种返回格式的对比.

·HTML片段

由于服务器端返回的数据格式是HTML片段,因此不需要经过处理就可以将新HTML

数据插入主页面中。JQuery代码如下:

$(function(){

         $("#send").click(function(){

                    $.get("get1.ashx",{

                                         username:  $("#username").val() ,

                                         content:  $("#content").val() 

                                  },function (data, textStatus){

                       $("#resText").html(data); // 把返回的数据添加到页面上

                                  }

                    );

         })

      })

HTML片段实现起来只需要很少的工作量,但这种固定的数据结构并不一定能够在其他的web应用程序中的到重用。

·XML文档

由于服务器端返回的数据格式是XML文档,因此需要对返回的数据进行处理,前面的章节已经介绍过jQuery强大的DOM处理能力,处理XML文档与处理HTML文档一样,也可以使用常规的attr()、find()、filter()以及其他方法,JQuery代码如下:

      $(function(){

         $("#send").click(function(){

                    $.get("get2.ashx ", {

                                  username:  $("#username").val() ,

                                  content:  $("#content").val() 

                    },function (data, textStatus){

                                  varusername = $(data).find("comment").attr("username");

                                  varcontent = $(data).find("comment content").text();

                    vartxtHtml= "<divclass='comment'><h6>"+username+":</h6><pclass='para'>"+content+"</p></div>";

          $("#resText").html(txtHtml); // 把返回的数据添加到页面上

                    });

         })

   })

返回数据格式为XML文档的过程实现是想起来比HTML片段要稍微复杂些,但XML文档的可移植性是其他数据格式无法比拟的,因此以这种格式提供的数据的重用性将极大提高。例如del.icio.us(http://del.icio.us),Flickr(http://flickr.com)和某些开放平台都是以XML格式输出的数据,读者可以利用它们提供的API,将获得的内容整合到自己的网站中(Mashup应用),不过,XML文档体积相对较大,与其他格式相比,解析和操作他们的速度都要慢一些。

·JSON文件

之所以出现这种数据格式的文件,很大程度上是因为XML文档体积大和难以解析,JOSN文件和XML文档一样,也可以方便的被重用。而且,JSON文件非常简洁,也容易阅读。想了解更多的JSON文档知识,可以访问http://json.org/网址。

由于服务器端返回数据格式是JSON文件,因此需要对返回的数据进行处理之后,才可以将新的HTML数据添加到主页面中。JQuery代码如下:

$(function(){

         $("#send").click(function(){

                    $.get("get3.ashx ", {

                                         username:  $("#username").val() ,

                                         content:  $("#content").val() 

                                  },function (data, textStatus){

                                      var username = data.username;

                                         varcontent = data.content;

var txtHtml = "<divclass='comment'><h6>"+username+":</h6><pclass='para'>"+content+"</p></div>";

          $("#resText").html(txtHtml); // 把返回的数据添加到页面上

                                  },"json");

             })

         })

在上面代码中,将$.get()方法的第4个参数(type)设置为“json”来代表期待服务器端返回的数据格式.

以上3种返回方式都可以达到图6-6所示的效果。

通过对3种数据格式的优缺点进行分析,可以得知在不需要与其它应用程序共享数据的时候,使用HTML片段来提供返回数据一般来说是最简单的,如果数据需要用,那么JSON文件是不错的选择,它的性能和文件的大小方面具有优势,而当远程应用程序未知时,XML是明智的选择,它是Web服务领域的“世界语”,具体选择哪种格式,并没有严格的规定,读者可以根据需求来选择最合适的返回格式来进行开发。

图6-6 将返回的数据添加到页面上

2.$.post()方法

它与$.get()方法的结构和使用方式都相同,不过他们之间仍然有以下区别。

(1) GET请求会将参数跟在URL后进行传递,而POST请求则是作为HTTP消息实体内容发送给Web服务器。当然,在Ajax请求中,这种区别对用户是不可见的。

(2) GET方式对传输的数据有大小的限制(通常不能大于2KB),而使用的POST方式传递的数据量要比GET方式大得多(理论上不受限制).

(3) GET方式请求的数据会被浏览器缓存起来,因此其他人就可以从浏览器的历史记录中读取到这种数据,列如账号和密码等。在某种情况下,GET方式会带来严重的安全性问题,而POST方式相对来说就可以避免这种情况。

(4) GET方式和POST方式传递的数据在服务器端的获取也不相同,在PHP中,GET方式的数据可以用$_GET[]获取,而POST方式可以用$ _POST[]获取,两种方式可以用$ _REQUEST[];来获取。

由于POST和GET方式提交的所有数据都可以通过$_REQUEST[];来获取,因此只需要改变jQuery函数,就可以将程序在GET请求和POST请求之间切换,代码如下:

$(function(){

         $("#send").click(function(){

                    $.post("get1.ashx ", {

                                         username:  $("#username").val() ,

                                         content:  $("#content").val() 

                                  },function (data, textStatus){

                    $("#resText").append(data); // 把返回的数据添加到页面上

                                  }

                    );

         })

      })

另外,当load()方法带有参数传递时,会使用POST方式发送请求。因此也可以使用load()方法来完成同样的功能。代码如下:

   $(function(){

         $("#send").click(function(){

                $("#resText").load("get1.ashx ",{

                                         username:  $("#username").val() ,

                                         content:  $("#content").val() 

                      })

         })

      })

上面使用load()、$.get()和$.post()方法完成了一些常规的Ajax程序,如果还需要编写一些复杂的Ajax程序,那么就需要用到JQuery中的$.ajax()方法。$.ajax()方法不仅能实现与load()、$.get()和$.post()同样的功能,而且还可以设定beforeSend(提交前回调函数)、error(请求失败后处理)、success(请求成功后处理)以及complete(请求完成后处理)回调函数,通过这些回调函数,可以给用户更多的Ajax提示信息。另外,还有一些参数,可以设置Ajax请求的超时时间或者页面的“最后更改”状态等等。关于$.ajax()方法将在后面的章节中进行讲解。

6.4.3  $.getScript()方法和$.getJson()方法

1.$.getScript()方法

有时候,在页面初次加载时就取得所需要的全部javaScript文件是完全没有必要的。虽然可以在需要哪个javaScript文件时,动态的创建<script>标签,jQuery代码如下:

$(document.createElement(“script”)).attr(“src”,”test.js”).appendTo(“head”);

或者

$(“<script src=’test.js’type=’text/javascript’ /> “).appendTo(“head”);

但这种方式并不理想。为此,jQuery()提供了$.getScript()方法来加载.js文件,与加载一个HTML片段一样简单方便,并且不需要对javaScript文件进行处理,javaScript文件会自动执行。

jQuery代码如下:

      $(function(){

      $('#send').click(function() {

            $.getScript('test.js');

      });

当“加载”按扭单击后,会出现图6-7所示的效果。

图6-7 $.getScript(“test.js”)方法调用成功

与其它Ajax方法一样,$.getScript()方法也有回调函数,它会在JavaScript文件成功载入后进行,例如想载入jQuery官方颜色动画插件(jquery.color.js),成功后给元素绑定颜色变化动画,就可以用到$.getScript()方法的回调函数。代码如下:

$(function(){

$.getScript('http://dev.jquery.com/view/trunk/plugins/color/jquery.color.js',function(){

                          $("<p>加载JavaScript完毕</p>").appendTo("body");

                             $("#go").click(function(){

                                     $(".block").animate( {backgroundColor: 'pink' }, 1000)

                                            .animate( { backgroundColor: 'blue'}, 1000);

                             });

                     });

   })

当jquery.color.js动画插件加载完毕后,单击id为“go”的按钮时,class为block的元素就有了颜色动画变化

2. $.getJson()

$.getJson()方法用于加载JSON文件,与$.getScript()方法的用法相同。

jQuery代码如下:

    $(function(){

       $('#send').click(function() {

                $.getJSON('test.json');

       });

    })

当单击“加载”按钮后,网页上看不到任何效果。虽然函数加载了JSON文件,但是并没有告诉javaScript对返回的数据如何处理。为此,jQuery提供了回调函数,在回调函数里处理返回的数据,代码如下:

$(function(){

       $('#send').click(function() {

            $.getJSON('test.json', function(data) {

              //data:返回的数据

})

      })

})

可以在函数中通过data变量来遍历相应的数据,也可以使用迭代方式为每个项构建相应的HTML代码。虽然在这里可以使用传统的for循环来实现,但既然是讲解jQuery,那么还是使用jQuery里的方法。jQuery提供了一个通用的遍历方法$.each(),可以用于遍历对象和数组。

$.each()函数不同于jQuery对象的each()方法,它是一个全局函数,不操作jQuery对象,而是以一个数组或对象作为第1个参数,以一个回调函数作为第2个参数。回调函数拥有两个参数:第1个为对象的成员或数组的索引,第2个为对应变量或内容。代码如下:

$(function(){

       $('#send').click(function() {

         $.getJSON('test.json', function(data) {

              $('#resText').empty();

                             var html = '';

                    $.each(data  , function(commentIndex, comment) {

                           html+= '<div class="comment"><h6>' + comment['username']

+ ':</h6><p class="para">'+ comment['content'] + '</p></div>';

                 })

                            $('#resText').html(html);

           })

      })

   })

在上面的代码中,当返回数据成功后,首先清空id为“resText”的元素的内容,以便重新构造新的HTML,然后通过$.each()循环函数依次遍历每个项,并将遍历出来的内容构建成HTML代码拼接起来,然后将构建好的HTML添加到id为“resText”的元素中。

当“加载按钮单击后,会出现图6-8所示的效果。

图6-8 $.getJSON(“test.json”)函数执行成功

不仅如此,还能通过使用JSONP形式的回调函数来加载其他网站的JSON数据,例如从图片网站(http://Flickr.com)搜索汽车类别的2张最新图片。代码如下:

$(function(){

   $('#send').click(function() {

$.getJSON("http://api.flickr.com/services/feeds/photos_public.gne?tags=car&tagmode=any&format=json&jsoncallback=?",function(data){

                           $.each(data.items,function( i,item ){

      $("<imgclass='para'/> ").attr("src", item.media.m).appendTo("#resText");

                                                       if( i == 1 ) {

                                                              returnfalse;

                                                       }

                                        });

                          }

          );

      })

   })

上面的函数再次用到全局函数$.each()来遍历数据,因为只需要2张图片,所以当i=1的时候就需要退出循环。在$.each()函数中,如果需要退出each循环,只要返回false即可。

当“加载”按扭单击后,从Flickr网站加载的2张最新的汽车图片就会被添加到页面中。效果如图6-9所示。

图6-9 加载Flickr网站的图片

6.4.4  $.ajax()方法

$.ajax()方法是jQuery最底层的Ajax实现。

它的结构为:

  $.ajax(options)

该方法只有一个参数,但在这个对象里包含了$.ajax()方法所需要的请求设置以及回调函数等信息,参数以key/value的形式存在,所有参数都是可选的,常用参数如表6-3所示。

表6-3  $.ajax()方法常用参数解释

参数名称

 类型

 说明

url

String

(默认为当前页地址)发送请求的地址

type

Stirng

请求方式(POST或GET)默认为GET。注意其他HTTP请求方法,例如PUT和DELETE也可以使用,但仅部分浏览器支持

timeout

Number

设置请求超时时间(毫秒),此设置将覆盖$.ajaxSetup()方法的全局设置

data

Object或String

发送到服务器的数据。如果已经不是字符串,将自动转换成字符串格式。GET请求中将附加在URL后。防止这种自动转换,可以查看processData选项。对象必须为key/value格式,例如{foo1:”bar1”,f002:”bar2”}转换为&foo1=bar1&foo2=bar2。如果是数组,jQuery将自动为不同值对应同一个名称,例如{foo[“bar1”,“bar2”]}转换为&foo=bar1&foo=bar2

dataType

String

预期服务器返回的数据类型。如果不指定,jQuery将自动根据HTTP包MIME信息返回responseXML或responseText,并作为回调函数参数传递。

xml:返回XML文档,可用jQuery处理。

Html:返回纯文本HTML信息;包含的script标签会在插入DOM时执行。

Script:返回纯文本JavaScript代码。不会自动缓存结果。除非设置了cache参数。注意在远程请求时(不在同一域下),所有POST请求都转换为CET请求。

Json:返回JSON数据。

Jaonp:JSONP格式。使用SONP形式调用函数时,例如myurl?callback=?,jQuery将自动替换后一个“?”为正确的函数名,以执行回调函数。

text:返回纯文本字符串。

beforeSend

Function

发送请求前可以可以修改XMLHTTPRequest对象的函数,例如添加自定义的HTTP头。在beforeSend中如果返回false可以取消本次Ajax请求。XMLHttpRequest对象是唯一的参数。function(XMLHttpRequest){this;//调用本次Ajax请求时传递的options参数

complete

Function

请求完后调用的回调函数(请求成功或失败时均调用)。参数:XMLHttpReauest对象和一个描述成功请求类型的字符串。function(XMLHttpRequest){this;//调用本次Ajax请求时传递的options参数

success

Function

请求成功后调用的回调函数,有两个参数。

(1)由服务器返回,并根据dataType参数进行处理后的数据。

(2)描述状态的字符串  Function(data,textStatus){

//data可能是xmlDoc、jsonObj、html、text等等    this;// 调用本次Ajax请求时传递的options参数}

}

                                    

Error

Function

请求失败后调用的回调函数,该函数有3个参数,即XMLHttpReauest对象、错误信息、捕获的错误对象(可选)。

Ajax事件函数如下:

Function(XMLHttpReauest,textStatus,errorThrown){

//通常情况下textStatus和errorThrown只有其中一个包含信息

this;// 调用本次Ajax请求时传递的options参数

}

Global

Boolean

默认为true,表示是否触发全局Ajax事件。设置为False将不会触发全局Ajax事件,AjaxStart或AjaxStop可用于控制各种Ajax事件。

如果需要使用$.ajax()方法来进行Ajax开发,那么上面这些常用的参数都必须了解。此外,$.ajax()方法还有其他参数,读者可以参考附录D的具体介绍。

前面用到的$.load()、$.get()、$.post()、$.getScript()和$.getJson()这些方法,都是基于$.ajax()方法构建的,$.ajax()方法是jQuery最底层的Ajax实现,因此可以用它来代替前面的所有方法。

例如,可以用下面的jQuery代码代替$.getScript()方法;

$(function(){

       $('#send').click(function() {

           $.ajax({

                      type: "GET",

                      url: "test.js",

                      dataType: "script"

                        });

       });

   })

再例如,可以用以下的jQuery代码代替$.getJSON()方法;

   $(function(){

       $('#send').click(function() {

           $.ajax({

                      type: "GET",

                      url: "test.json",

                      dataType: "json",

                      success : function(data){

                             $('#resText').empty();

                                    var html = '';

                                    $.each( data , function(commentIndex, comment) {

             html+= '<div class="comment"><h6>' + comment['username'] +':</h6><p class="para">' + comment['content'] +'</p></div>';

                                    })

                                   $('#resText').html(html);

                      }

                    });

       });

   })

6.5 序列化元素

1.   serialize()方法

做项目的过程中,表单是必不可少的,经常用来提供数据,例如注册、登陆等,常规的方法是使表单提交到另一个页面,整个浏览器都会被刷新,而是用Ajax技术则能够异步地提交表单,并将服务器返回的数据显示在当前页面中。

前面在讲解$.get()和$.post()方法的时候,表单的HTML代码如下:

<form id="form1">

<p>评论:</p>

 <p>姓名: <input type="text" name="username"id="username" /></p>

 <p>内容: <textarea name="content" id="content"></textarea></p>

      <p><input type="button" id="send"value="提交"/></p>

</form>

为了获取姓名和内容,必须将字段的值逐个增加到data参数中,代码如下:

$("#send").click(function(){

      $.get("get1.ashx ",{

             username:$("#username").val(),

             content:$("#content").val()

      },function(data,textStatus){

             $("#resText").html(data);

      })

})

这种方式在只有少量字段的表单中,勉强还可以使用,但如果表单元素越来越复杂,使用这种方式在增大工作量的同时也使表单缺乏弹性,jQuery为这一常用的操作提供了一个简化的方法——serialize()与jQuery中其他方法一样,serialize()方法也是作用于一个jQuery对象,它能够将DOM元素内容序列化为字符串,用于Ajax请求,通过使用serlialize()方法,可以把刚才的jQuery代码改为如下:

$("#send").click(function(){

      $.get("get1.ashx ",$("#form1").serialize(),function  (data,textStatus){

      $("#resText").html(data);

});

});

当单击“提交”按钮后,也能达到同样的效果,如图6-10所示。

图6-10 使用serialize()方法

即使在表单中再增加字段,脚本仍然能够使用,并且不需要做其他多余工作。

需要注意的是,$.get()方法中data参数不仅可以使用映射方式,如以下jQuery代码:

{

      username:$("#username").val(),

      content:$("#content").val()

}

也可以使用字符串方式,如以下jQuery代码:

"username="+encondeURIComponent($("#username").val())+

"&content="+encondeURIComponent($("#content").val())

用字符串方式时,需要注意对字符编码(中文问题),如果不希望编码带来麻烦,可以使用serialize()方法,它会自动编码。

因为serialize()方法用于jQuery对象,所以不光只有表单能使用它,其他选择器选取的元素也都能使用它,以下jQuery代码:

$(":checkbox,:radio").serialize();

把复选框和单选框的值序列化为字符串形式,只会将选中的值序列化。

2.serializeArray()方法

在jQuery中还有一个与serialize()类似的方法——serializeArray(),该方法不是返回字符串,而是将DOM元素序列化后,返回JSON格式的数据。

jQuery代码如下:

varfields=$(":checkbox,:radio").serializeArray();

console.log(fields);

通过console.log()方法输出fields对象,然后在Firebug中查看该对象,如图6-12所示的userObjects对象。

既然是一个对象,那么就可以使用$.each()函数对数据进行迭代输出,代码如下:

$(function(){

      varfields=$(":checkbox,:radio").serializeArray();

      console.log(fields);

      $.each(fields,function(i,field){

             $("#results").append(field.value+",");

})

})

3.$.param()方法

它是serialize()方法的核心,用来对一个数组或对象按照key/value进行序列化。比如将一个普通的对象序列化:

var obj=(a:1,b:2,c:3);

var k=$.param(obj);

alert(k);

6.6 jQuery中的Ajax全局事件

jQuery简化Ajax操作不仅体现在调用Ajax方法和处理响应方面,而且还体现在对调用Ajax方法的过程中的HTTP请求的控制。通过jQuery提供了一些自定义全局函数,能够为各种与jax相关的事件注册回调函数。例如当Ajax请求开始时,会触发ajaxStart()方法的回调函数:当Ajax请求结束时,会触发ajaxStop()方法的回调函数。这些方法都是全局的方法,因此无论创建它们的代码位于何处,只要有Ajax请求发生时,就会触发它们。在前面例子中,远程读取Flickr.com网站的图片速度可能会比较慢,如果在加载的过程中,不给用户提供一些提示和反馈信息,很容易让用户误认为按钮单击无用,使用户网站失去信心。

此时,就需要为网页添加一个提示信息,常用的提示信息是“加载中...”,代码如下:

<div id="loading">加载中...</div>

然后用CSS控制元素隐藏,当Ajax请求开始的时候,将此元素显示,用来提示用户Ajax请求正在进行。当Ajax请求结束后,将此元素隐藏,代码如下:

$("#loading").ajaxStart(function(){

      $(this).show();

});

$("#loading").ajaxStop(function(){

      $(this).hide();

});

这样一来,在Ajax请求过程中,只要图片还未加载完毕,就会一直显示“加载中...”的提示信息,看似很简单的一个改进,却将极大地改善用户的体验,效果如图6-11所示。

图6-11 显示“加载中…”的提示信息

如果在此页面中的其他地方也使用Ajax,该提示信息仍然有效,因为它是全局的,如图6-12所示。

图6-12 demo2也使用同一个提示信息

jQuery的Ajax全局事件中还有几个方法,也可以在使用Ajax方法的过程中为其带来方便,如表6-4所示。

表6-4 另外几个方法

方法名称

说明

ajaxComplete(callback)

Ajax请求完成时执行的函数

ajaxError(callback)

Ajax请求发生错误时执行的函数,捕捉到的错误可以作为最后一个参数传递

AjaxSend(callback)

Ajax请求发送前执行的函数

ajxaSuccess(callback)

Ajax请求成功时执行的函数

注意:如果想使某个Ajax请求不受全局方法的影响,那么可以在使用$.ajax(options)方法时,将参数中的globle设置为false,jQuery代码如下:

$.ajax({

url:”loadtest.htm”,

globle:false//不触发全局Ajax事件

})

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值