javascript的核心API设计的很简单,但因为浏览器之间的不兼容性,致使客户端的API过于复杂。IE9的到来缓解了这种状况。然而使用javascript的框架或者工具类库,能简化通用操做,处理浏览器之间的差别,这让不少程序员在开发web应用时变得更简单。javascript
jQuery类库被普遍的使用,做为web开发者,咱们必须熟悉它:即使没有在本身的代码中遇到,也可能在别人的代码中碰见。幸运的是,jQuery代码足够小巧和稳定,本章就能将它讲述清楚。
jQuery能让你在文档中轻松找到关心的元素,并对这些元素进行操做:添加内容、编辑HTML属性和css属性、定义事件处理程序,以及执行动画。它还拥有Ajax工具来动态发起HTTP请求,以及一些通用的工具函数来操做对象和数组。css
正如其名,jQuery类库聚焦于查询。一个典型的查询使用CSS选择器来识别一组文档元素,并返回一个对象来表示这些元素。返回的对象提供了大量的方法来批量操做匹配的元素。这些方法会尽量返回调用对象自己,这使得简洁的链式调用成为可能。jQuery如此强大和好用,关键得益于如下特性:html
本章首先会介绍如何使用jQuery来实现 简单的查询并操做其结果。接下来的章节会讲解:java
1.jQuery基础node
jQuery类库定义了一个全局函数:jQuery()。该函数使用频繁,所以在 类库中还给它定义了一个别名:$,这是jQuery在全局命名空间中定义的惟一两个变量。(若是你在本身的代码中有使用$做为变量,或者引入了Prototype等使用$做为全局变量的类库,这时,为了不冲突,可使用jQuery.noConflict()来释放$变量,让其指向原始值。)
这个拥有两个名字的全局方法是jQuery的核心查询方法,例以下面的代码能获取jQuery文档中的全部<div>元素:jquery
var divs = $("div")
改方法返回的值表达零个或多个DOM元素,这就是jQuery对象。注意:jQuery()是工厂函数,不是构造函数,它返回一个新建立的对象,但并无和new关键字一块儿使用。jQuery对象定义了不少方法,能够用来操做它们表示这组元素,本章中的大部分文字来阐述这些方法。例如:下面的这组代码用来找到拥有details类的p元素,将其高亮显示,并将其中隐藏的p元素快速显示出来。css3
$("p.details").css("background-color","yellow").show("fast");
上面的css()方法调用操做的jQuery对象是由$()返回的,css()方法返回的这个也是这个对象,所以能够继续调用show()方法,这就是链式调用,很简洁紧凑。在jQuery编程中,链式调用这个习惯用语很广泛。再举个例子,下面的代码能够找到文档中拥有"clicktohide"CSS类的全部元素,并给每个元素都注册一个事件处理函数。当用户单击元素时,会调用事件处理程序,使得元素缓慢向上收缩,最终消失。程序员
$(".clicktohide").click(function(){$(this).slideUp("slow");});
i.jQuery()函数web
在jQuery类库中,最重要的方法是jQuery()方法,(也就是$())。它的功能很强大,有四种不一样的调用方式。ajax
第一种也是最经常使用的调用方式是传递CSS选择器(字符串)给$()方法。当经过这种方式调用时,$()方法会返回当前文档中匹配该选择器的元素集。jQuery支持大部分css3选择器语法,还支持一些本身的扩展语法。8小节i节将阐述jQuery选择器的语法。还能够将一个元素或jQuery对象做为第二个参数传递给$()方法,这时返回的是该特定元素或元素的子元素中匹配选择器的部分。第二个参数是可选的,定义了元素的查询的起点,常常称为上下文(context)。
第二种调用方式是传递一个Element、Document或window对象给$()方法。在这种状况下,$()方法只须简单地将Element、Document或window对象封装成jQuery对象并返回。这样可使得能用jQuery方法来操做这些元素而不使用原生的DOM方法。例如,在jQuery程序中,常常能够看见$(document)或$(this)。jQuery对象能够表示文档中多个元素,也能够传递一个元素数组给$()方法。在这种状况下,返回的jQuery对象表示该数组中的元素集。
第三种调用方式是传递HTML文本字符串给$()方法。这这种状况下,jQuery会根据传入的文本建立好HTML元素并封装为jQuery对象返回。jQuery不会将刚建立的元素自动插入文档中,可使用第3节描述的jQuery方法将元素插入到想要的地方。注意,在这种调用下,不可传入纯文本,由于jQuery会把纯文本当作是CSS选择器来解析。当使用这种调运风格时,传递给$()字符串必须至少包含一个带尖括号的HTML标签。
经过第三种方式调用时,$()接受可选的第二参数。能够传递Document对象来指定与所建立关联的文档。(好比,当建立的元素要插入iframe里时,须要显式的指定iframe的对象。)第二参数还能够是object对象。此时。假设该对象的属性表示HTML属性的键/值对,这些属性将设置到所建立的对象上。当第二参数对象的属性名是css,html,text,width,heigeht,offset,val,data或者属性名是jQuery事件处理程序注册方法名时,jQuery将调用新建立元素上的同名方法,并传入属性值。(css(),html(),text()等方法将在第2节讲述,事件处理程序注册方法将在第4节讲述),例如:
var img = $("<img>", //新建一个<img>元素 { src: url, //具备html属性 css: {borderWidth: 5}, //css样式 click: handClick //和事件处理程序 });
第四种调用方式是传入一个函数给$()方法。此时,当文档加载完且DOM程序能够操做时,传入函数将被调用。这是常见onLoad()函数的jQuery版本。在jQuery程序中,在jQuery()里定义一个匿名函数很是常见:
jQuery(function(){//文档加载完毕时调用 //全部的代码放在这里 });
有时候咱们还能够看见老式的写法$(f)和完整的写法
$(document).ready(f)
传递给jQuery()的函数在被调用时,this指向document对象,惟一的的参数指向jQuery函数 。这意味这能够释放全局的$()函数,但在内部依旧能够延续该习惯:
jQuery.noConflict();//还原$()为初始值 jQuery(function($){ //让$()成为jQuery对象的局部别名 //jQuery代码 });
经过$注册的函数将在DOMContentLoaded事件触发时由jQuery触发。当浏览器不支持该事件时,会在load事件触发时由jquery触发。这意味这文档已经完毕,但图片等外部资源还有可能未加载完。若是DOM准备就绪后再传递函数给$(),传递的函数会在$()返回以前马上调用。
jQuery类库还使用jQuery()函数做为其命名空间,在下面定义了很多的工具函数和属性。好比jQuery.noConflict();就是其中的一个工具函数。还包括遍历的jQuery.each(),以及用来解析JSON文本的jQuery.parseJSON()。第7节例举了这些通用函数,jQuery的其它函数在本章中都会说起。
jQuery术语
在本章中会提到一些重要的术语和短语,咱们来看下其定义
jQuery对象:
jQuery函数是jQuery或$()的值。该函数能够用来建立jQuery对象,用来注册DOM就绪时须要调用的处理程序,还用作jQuery命名空间。咱们经常使用$()来引用它。它能够用来作命名空间,所以,jQuery函数也可称为"全局jQuery对象",但要千万注意,不要把它和"jQuery对象"混淆。
jQuery对象
jQuery对象是由jQuery函数返回的对象。一个jQuery对象表示一组文档元素,也叫“jQuery结果”,“jQuery集”或“包装集”。
jQuery函数
jQuery函数是指定义在jQuery命名空间中的函数,好比jQuery.noConflict()。jQuery函数也称为“静态方法”。
jQuery方法
jQuery方法是由jQuery函数返回的jQuery对象的方法。jQuery类库最重要的部分就是它定义的这些强大的方法,
jQuery函数和jQuery方法有时很难区分,所以有部分函数和方法的名称是同样的:注意如下两行代码的差别:
//jQuery的each()函数用来对数组a中的每个元素都调用一次函数f $.each(a,f); //调用jQuery()函数获取表示文档中全部<a>元素的jQuery对象 //而后调用该jQuery对象的each()方法,对选中的每个元素调用一次函数f $("a").each(f)
ii.查询与查询结果
传递css选择器字符串给$(),它返回的jQuery对象表示匹配(或称为“选中”)的元素集。css选择器在13.2.iiiii介绍过
$()返回值是一个jQuery对象,jQuery对象是类数组,它们拥有length属性和介于0~length-1之间的数值属性。(7章11节有更多类数组对象的信息),这意味着可使用标准的数组标识方括号来访问jQuery对象的内容。
$("body").length //=>1 文档只要一个惟一的body元素 $("body")[0] //等于document.body
若是不想把数组标识用来jQuery对象上,可使用size()方法来替代length属性,用get()方法来代替方括号索引。可使用toArray方法来说jQuery对象转化为真实数组。
除了length属性,jQuery对象还有三个挺有趣的属性。selector属性是建立jQuery对象时选择器字符串(若是有的话)、context属性是上下文对象,是传递给$()方法第二参数,若是没有,默认是Document对象。最后,全部jQuery对象都在一个名为jquery的属性,检测改属性是否存在能够简单便捷地将jQuery对象与其余类数组对象区分开来。jQuery属性值是字符串形式的jQuery版本号
//获取document body中的全部<script>元素 var bodyscript = $("script",document.body); bodyscript.selector;//=>script bodyscript.context; //=>document.body bodyscript.jquery;//=> "1.8.3"
$()与querySelectorAll()
$()函数与13章2节iiiii节描述的Document对象的querySelectorAll()方法相似:二者都有css选择器做为参数,而且返回类数组对象来存放匹配选择器的元素。在支持querySelectorAll()的浏览器中,jQuery实现调用会调用querySelectorAll()方法,然而,在代码中使用$()代替querySelectorAll()依旧是很好的选择:
想要遍历jQuery对象中的全部元素时,能够调用each()方法来代替for循环,each()方法有点相似ECMAScript5(ES5)中的forEach()数组方法。它接受一个回调函数做为惟一的参数,而后对jQuery对象的中每个元素(按照文档中的顺序)调用回调函数。回调函数做为匹配元素的方法来调用,所以,在回调函数里this关键字指代Element对象。
each()方法还会将索引值和该元素做为第一个和第二个参数传递给回调函数。注意:this和第二参数都是原生文档元素,而不是jQuery对象;若是想使用jQuery方法来操做该元素,须要先用$()封装它。
jQuery的each()方法和forEach()有一个显著的区别:若是回调函数在任一个元素上返回false,遍历将在该元素停止(就像在普通循环中使用break关键字同样)。each()返回调用自身的jQuery对象,所以它能够用于链式调用。下面这个例子(使用prepend方法将在第三小节阐述):
//给文档中的div元素标号,从开始一直到div#last(包含边界值) $("div").each(function(idx){//找到div元素,而后遍历它们 $(this).prepend(idx + ":");//找到没一个元素前面插入索引值 if(this.id === "last") return false;//碰到#last元素时终止 });
尽管each()方法很强大,可是用的并很少,由于jQuery方法一般隐式遍历匹配元素集并操做它们。须要使用到each()的典型场景须要不一样的方式操做匹配的元素集并操做它们。须要使用each()的典型场景是须要不一样的方式来操做匹配的元素。即使如此,也不须要调用each(),由于jQuery的一些方法容许传递回调函数。
在ECMAScript数组方法规范以前,jQuery类库就已经存在了。jQuery定义了几个方法,其功能和ECMAscript5方法功能相似。jQuery的map()方法和Array.prototype.map()的方法很相近。
它接受回调函数做为参数,并为jQuery对象中的没一个元素都调用回调函数,同时将回调函数的返回值收集起来,并将这些返回值封装成一个新的jQuery对象返回。map()调用回调函数的方式和each()方法相同:元素做为this值和第二参数传入,元素的索引值做为第一参数传入。若是回调函数返回null或undefined,该值将被忽略,在本次调用中不会有任何新元素添加到新的jQuery对象中。若是回调函数返回数组或类数组对象(好比jQuery对象),将会扁平化它并将其中的元素一个个添加到新的jQuery对象中。注意:由map()返回的jQuery对象能够不包含文档元素,但它依旧能够像类数组对象同样使用:例如
//找到全部标题元素,映射到它们的id,并转化为真实数组,而后排序 $(":header").map(function(){return this.id;}).toArray().sort();
除了each()和map()以外,jQuery的另一个基础方法是index()。该方法接受一个元素做为参数,返回值是该元素在此jQuery对象中的索引值,若是找不到的话,则返回-1。显然,受jQuery的典型风格影响,index()方法有多个重载版本。传递一个jQuery对象做为参数,index()方法会对该对象的第一个元素进行搜索。若是传入的是字符串,index()会把它当成css选择器,并返回该jQuery对象中匹配该选择器的一组元素中的第一个元素的索引值。若是什么参数都不传入,index()方法返回该jQuery对象中第一个毗邻元素的索引值。
这里要讨论的最后一个通用的jQuery方法是is()。它接收一个选择器做为参数,若是选中元素中至少有一个匹配该选择器时,则返回true。能够在each()回调函数中使用它,例如:
if($(this).is(":hidden")) return;//跳过隐藏元素 //对可见元素作点什么 });
2.jQuery的getter和setter
jQuery对象上最简单、最多见的操做是获取(get)或设置(set)HTML属性、css样式、元素内容和位置高宽的值。该节讲述这些方法。首先,让咱们对jQuery中的getter和setter方法有个概要理解。
在阅读本节接下来的内容时,请将对getter和setter的概要要理解牢记于心。下面的每一节会讲述jQuery getter/setter方法中的一个重要类别
i.获取和设置HTML属性
attr()方法是jQuery中用于HTML属性的getter/setter,它符合上面描述的概要和理解中的每一条。attr()处理浏览器的兼容性和一些特殊状况,还让html属性名和javascript属性名能够等同使用(当两者存在差别时)例如,可使用"for"也可使用"htmlFor",可使用"class"也可使用"className".一个相关函数是removeAttr(),可用来从全部选中元素中移除某个属性。下面是一些例子:
$("form").attr("action"); $("#icon").attr("src", "ico.gif"); //设置src属性 $("#banner").attr({ //一次性设置4个属性 src: "banner,gif", alt: "advertisenment", width: 720, height: 64 }); $("a").attr("target","_blank");//使全部连接在新窗口打开 $("a").attr("target",function(){ //非站内的连接在新窗口中打开 if(this.host == location.host) return "_self" else return "_blank"; }); $("a").attr({target:function(){...}}); //能够像这样传入函数 $("a").removeAttr("target");//
ii.获取和设置CSS属性
css()方法和attr()方法很相似, 只是css()方法做用于元素的css样式,而不是元素的HTML属性。在获取元素样式值时,css()返回的是当前样式,而不是元素的HTML属性。在获取样式值时,css()返回的是当前样式(或称为“计算”样式,参考14章4节):返回值可能来自style属性也可能来自样式表,注意:不能获取复合样式的值,好比:font或margin。而获取单个样式的值,font-weiht、margin-top等、
在设置样式时,css()方法会将样式简单添加到元素的style属性中。css()方法容许在CSS样式名中使用联系的字符串("background-color")或使用驼峰式javascript样式名("backgroundColor")。在获取样式值时,css()会把数值转换为带有点位的后缀字符串返回。而在设置样式值时,则会将数值转化为字符串,在必要的时候添加"px"等单位后缀。
$("h1").css("font-weight"); $("h1").css("font-size"); $("h1").css("font"); //错误,不能获取复合样式的css属性 $("h1").css("font-variant", "small-caps"); //该属性主要用于定义小型大写字母文本 $("div").css("border", "solid black 2px"); //这样设置复合属性是没问题的 $("h1").css({ backgroundColor: "black", //一次性设置多个样式 color: "white" }); //让全部的<h1>字体大小增长25% $("h1").css("font-size", function(i, curval) { return Math.round(1.25 * parseInt(curval)); });
iii.获取和设置css类
回忆一下,class属性值(在javascript里经过className访问)会被解析称为一个由空格风格的CSS类名列表。一般,咱们想要往列表中添加、删除某一项,或判断某一想是否在列表中,而不是将该列表替换为另外一个。所以,jQuery定义了一些便捷方法来操做class属性。addClass()和removeClass()用来从选中元素中添加和删除类。toggleClass()的用途是,当元素尚未某些类时,给元素添加这些类,反之,则删除。hasClass()用来判断某类是否存在,下面是一些例子:
//添加css类 $("h1").addClass("hilite"); //给全部的h1添加一个class $("h1+p").addClass("hilite firest"); //给h1后面的p添加两个类 $("section").addClass(function(n){ //传递一个元素添加自定义类 return "section" + n; //每一个元素添加自定义类 }); //删除CSS类 $("p").removeClass("hilite");//从全部p元素中删除一个类 $("p").removeClass("hilite first");//一次性删除多个类 $("section").removeClass(function(n){ //删除元素中自定义的类 return "section" + n; }); $("div").removeClass(); //删除全部<div>中的全部类 //切换CSS类 $("tr:odd").toggleClass("oddrow");//若是该类不存在则添加 //存在则删除 $("h1").toggleClass("big samll"); //一次切换两个类 $("h1").toggleClass(function(n){ //切换函数计算出来的类 return "big bold h1-" +n; }); $("h1").toggleClass("hilite",true); //做用相似addClass $("h1").toggleClass("hilite",false); //做用相似removeClass //检测css类 $("p").hasClass("first"); //是否全部p元素都有该类? $("#lead").is(".first"); //功能和上面相似 $("#lead").is(".first.hilite"); //is()比hasClass()更灵活
注意:hasClass()不如addClass()、removeClass()、toggleClass()灵活。hasClass()只能接受单个类名做为参数,而且不支持函数参数。当选中元素中任意元素有指定的CSS类时,HasClass()返回true;若是什么元素都没有,则返回false,上面的is()方法更灵活,能够作一样的事情。
jQuery的这些方法和14章5节的classList方法相似,只是jQuery方法能够工做在全部的浏览器中,而不是支持css3的浏览器。此外,毫无疑问jQuery的方法能够操做多个元素并支持链式调用。
iiii.获取和设置HTML表单值
val()方法用来设置和获取HTML表单元素的value属性,还能够用于获取和设置复选框、单选按钮以及<select>元素的选中状态。
$("#surname").val(); //获取surname 文本域的值 $("#usstate").val(); //从<select>中选取单一值 $("select#extras").val(); //从<select multiple>中获取一组值 $("input:radio[name=ship]:checked").val(); //获取单选选中按钮的值 $("#email").val("invalid email address"); //给文本域设置值 $("input:checkbox").val(["op1","op2"]) //选中带有这些名字或值的复选框 $("input:text").val(function(){//重置全部文本域为默认值 return this.defaultValue; });
iiiii.设置和获取元素内容
text()和html()方法用来获取和设置元素的纯文本或HTML内容。当不带参数调用时,text()返回全部匹配元素的全部子孙文本节点的纯文本内容。该方法甚至能够发展在不支持textContent或innerText属性(13章5节ii)的浏览器中。
若是不带参数调用html()方法,它会返回第一个匹配元素的HTML内容。jQuery使用innerHTML属性来实现:x.html()和x[0].innerHTML同样高效
若是传入字符串给text()或html(),该字符串会用作该元素的纯文本或格式化的html文本内容,它会替换掉全部存在的内容。和其余setter方法同样,咱们还能够传入函数,此函数用来计算表示新内容的字符串:
var title = $("head title").text(); //获取文本标题 var headline = $("h1").html(); //获取第一个<h1>元素的HTML $("h1").text(function(n,current){//给每个标题添加章节号 return "§" + (n+1) + ":" + current });
iiiiii.获取和设置元素的位置高宽
在13章8节中咱们知道经过一些技巧能够正确获取元素的大小和位置,尤为当浏览器不支持getBoundClientRect(13章8节ii)时,使用jQuery方法能够更简单的获取元素的大小和位置,并兼容全部浏览器。注意:本节描述的全部方法都是getter,只有少部分能够用做setter。
使用offset()方法能够获取或设置元素的位置 。该方法相对文档来计算位置值,返回一个对象,带有left和top属性,用来表示x和y坐标。若是传入带有这些属性的对象给该方法,它会给元素设置指定的位置。在有必要时,会设置CSS的position属性来是的元素可定位:
var elt = $("#sprite"); //选择要移动的元素 var position = elt.offset(); //获取当前元素的位置 position.top += 100; //改变y坐标 elt.offset(position); //重新设置位置 //将全部的<h1>元素向右移动,移动的距离取决于他们在文档中的位置 $("h1").offset(function(index, curpos) { return { left: curpos.left + 25 * index, top: curpos.top }; });
postion()方法很像offset()方法,但它只能用做getter,它返回的元素位置是相对于其偏移父元素的,而不是相对文档的。在13章8节iiiii中,咱们知道任何一个元素都有一个offsetParent属性,其位置是相对的。定位元素总会当作其子孙元素的偏移父元素,但在某些浏览器下,也会把表格单元格等其余元素当成偏移父元素。jQuery只会把定位元素做为偏移父元素。jQuery对象的offsetParent()方法则会把每一个元素的映射到最近的定位祖先元素或<body>元素。注意这些方法的名字并不很恰当:offset()返回元素的绝对位置,相对于文档的坐标来表示。而postion()则返回相对元素的offsetParent()的偏移量。
对于获取元素的宽度的getter有3个,获取的高度也有3个。
width()和height()方法返回基本的宽度和高度,不包含内边距 、边框和外边距。
innerWidth()和innerHeight()返回元素的宽度和高度,包含内边距的宽度和高度(“内”表示这些方法度量的是边框之内的尺寸)。
outerWidth()和outerHeight()一般返回的是包含元素内边距和边框的尺寸。若是向两个方法中任意一个传入true值,他们还能够返回包含元素外边距的尺寸。下面代码展示了如何获取一个元素的4种不一样宽度:
var body = $("body"); var contenetWidth = body.width(); var paddingWidth = body.innerWidth(); var borderWidth = body.outerWidth(); var marginWidth = body.outerWidth(true); var padding = paddingWidth - contenetWidth; //左内边距和右内边距的和 var borders = borderWidth - paddingWidth; //左边框和右边框的和 var margins = marginWidth - borderWidth; //左外边距和右边距的和
width()和height()方法拥有其它4个方法(以inner和outer开头的方法)所没有的特性,首先,当jQuery对象的第一个元素是Window或Document对象时,width()和height()返回的是窗口的视口大小或文档的总体尺寸。其它方法只适用于元素,不适合窗口和文档。
另外一个特性是width()和height()方法能够是setter()也能够是getter()。若是传递值给这些方法,他们会给jQuery对象中的每个元素设置宽度或高度。(注意:不能给window和document对象对象设置宽度或高度。)若是要传入数值,会把它当成单位为像素的尺寸。若是传入字符串,会把它用做css的width和height属性的值,所以可使用任何css单位。最后,和其余setter相似 ,能够传入函数,用来计算要设置的宽度或高度。
在width()和height()的getter和setter行为之间有个小的不对称。用做getter时,这些方法返回元素的内容盒子尺寸,不包括内边距、边框和外边距。用作setter()时,他们只是简单的设置CSS的width和height属性。默认的状况下,这些属性也指定内容盒子的大小。可是,若是一个元素的CSS box-szing属性(14.2.iii)设置为border-box,则width()和height()方法设置的尺寸包括内边距和边框。对于使用context-box做为盒模型的元素e,调用$(e).width(x).width()返回x值。然而,对于使用border-box模型的元素,这种状况下通常不会返回x值。
与位置尺寸相关的最后与对jQuery方法是scrollTop()和scrollLeft(),可获取或设置元素滚动条的位置。这些方法能够用在window对象以及Document元素上,当用在Document对象上时,会获取或设置存放改Document的window对象的滚动条位置。与其余setter不一样,不可传递函数给scrollTop()和scrollLeft()。
可以使用scrollTop()做为getter和setter,与height()方法一块儿,来定义一个方法:根据指定的页面数向上或向下滚动窗口
//根据页面数n来滚动窗口。 n能够是分数也或负数 function page(n){ var w = $(window); //将window封装为jQuery对象 var pagesize = w.height(); //获得页面大小 var current = w.scrollTop(); //获得当前滚动条的位置 w.scrollTop(current + n*pagesize);// 设置新的滚动条位置 }
iiiiiii.获取和设置元素数组
jQuery定义了一个名为data()的getter/setter方法 ,用来设置或获取与文档元素、Document或Window对象相关联的数据。能够将数据与任意元素关联是很重要和强大的一项能力:这是jQuery的事件处理程序注册和效果队列机制的基础,有时,咱们还会再本身的代码中使用data()方法。
须要将数据与jQuery对象中的元素关联,传递名称和值两个参数给data()便可。还能够传递一个对象给data() setter,此时,该对象的每个属性都将用作名/值对,用来与jQuery对象的元素关联。注意,传递对象给data()时,该对象的属性将替换掉与元素相关联的旧数据。其其它不少setter方法不一样,data()不接受函数参数。当将函数做为第二参数传递给data()时,该函数会存储,就和其余值同样。
固然,data()方法也能够用作getter。当不带参数调用时,它会返回一个对象,含有与jQuery对象中的第一个元素相关联的全部名/值对。当传入一个字符串参数调用data()时,它会返回对已第一个元素与该字符串相关联的数据值。
removeData()方法从元素中删除数据。(使用data()设置值为null或undefined和实际上删除该值并非同一回事。)若是传递字符串给removeData(),该方法会删除元素中与该字符串相关联的值。若是不带参数调用removeData(),它会删除与元素相关联的全部数据。
$("nodes").data("x",1);//设置一些数据 $("div.nodata").removeData("x"); //删除一些数据 var x = $('#nodes').data("x"); // 获取一些数据
jQuery还定义了data()和removeData()方法的工具函数形式。要给单一元素e关联数据,可使用data()方法形式,也可使用其函数形式:
$(e).data(...) //方法形式 $.data(e,...) //函数形式
jQuery的数据框架没有将元素数据当作元素的属性来存储,但它的确须要给元素添加一个特殊的属性来与数据关联。因为某些浏览器不容许添加属性到<applet>、<object>和<embed>元素中,所以,jQuery根本不容许给这些类型的元素关联数据。
3.修改文档结构
咱们在2节iiiii节中咱们知道html()和text()方法用来设置元素内容。本节将讲述能对文档作出更复杂的修改的方法。HTML文档表示为一棵节点树,而不是一个字符的线性序列,所以插入、删除、替换、操做不会像操做字符串和数组同样简单。接下来的内容会阐释用于文档修改的jQuery的各类方法。
i.插入和替换元素
让咱们从基本的插入和替换方法开始。下面演示的每个方法都接受一个参数,用于指定须要插入文档中的内容。该参数能够是用于指定新内容的纯文本或html字符串,也能够是jQuery对象、元素或文本节点。根据调用的方法不一样,会在选中元素的里边,前面,或后面插入内容。若是待插入的内容是已存在于文档中的元素,会从当前的位置移走它。若是它须要插入屡次,在必要的时会复制该元素。这些方法都返回自身的jQuery对象。注意,在replaceWith()运行后,该jQuery对象中的元素将不存在于文档中:
$("#log").append("<br/>" + message); //在#log元素结尾处添加内容 $("h1").prepend("§"); //在每一个<h1>的起始处添加章节标识符 $("h1").before("<hr/>"); //在每一个<h1>的前面添加水平线 $("h1").after("<hr/>"); //在每一个<h1>的后面添加水平线 $("hr").replaceWith("<br/>") //将<hr/>元素替换为<br/> $("h2").each(function(){//将<h2>替换为<h1>,保持内容不变 var h2 = $(this); h2.replaceWith("<h1>" + h2.html() + "</h1>"); }); // after()和before()也可用在文本节点上 // 这是给每一个<h1>的开头添加上章节标识符的另外一种方法 $("h1").map(function(){ return this.firstChild; }).before("§")
这5个用于结果修改的方法都接受函数参数,原理啊计算出须要插入的值。和日常同样,若是传入参数,该函数会为每一个选中的元素调用一次。this指向该元素,在jQuery对象中元素的索引值将做为第一参数。对于append()、prepend()个replaceWidth(),第二参数将是该元素当前内容的HTML()字符串形式。对于before()和after(),该函数在调用时没有第二参数。
上面演示的5个方法都在目标元素上调用,并传入须要插入的内容做为参数。这5个方法中的每个均可以找到另外一个方法来实现差很少同样的功能,只要采用不一样的操做方式便可:在内容上调用,并传入目标元素做为参数。下面展现了这些方法对:
操做 | $(target).method(content) | $(content).method(target) |
在目标元素的结尾处插入内容 | append() | appendTo() |
在目标元素的起始处插入内容 | prepend() | preprendTo() |
在目标元素的后面插入内容 | after() | insertAfter() |
在目标元素的前面插入 内容 | before() | insertBefore() |
将目标元素替换为内容 | replaceWith() | replaceAll() |
想要理解这几个方法,有几个重要事项
若是传递字符串给第二列中的方法,会把它当作须要插入的HTML字符串。若是传递字符串给第三列中的方法,会把它当作选择器,用来标识目标元素。(也能够直接传入jQuery对象、元素或文本节点来指明目标元素)
第三列的方法不接受函数参数,第二栏中的方法能够。
第二列中的方法返回调用自身的jQuery对象。该jQuery对象中的元素有可能有新内容或新兄弟节点,但这些元素自身没有修改。第三列中的方法在插入的内容上调用,返回一个新的jQuery对象,表示插入操做后的新内容。特别注意,当内容被插入多个地方时,返回的jQuery对象将为每个地方保留一个元素。
上面例举了不一样点,下面的代码将实现与上面代码同样的操做,使用的是第三列的方法来替代第二列中的。注意在第二行中的代码不能传入纯文本(不带任何<>括号来标识它为HTML)给$()方法--它会被当作选择器。所以,必须显式建立须要插入的文本节点:
$("<br/> + message").appendTo("#log"); //添加html到#log中 $(document.createTextNode("§")).prependTo("h1"); //给全部<h1>添加文本节点 $("<hr/>").insertBefore("h1"); //在全部的<h1>前面插入水平线 $("<hr/>").insertAfter("h1"); //在全部的<h1>后面插入水平线 $("<br/>").replaceAll("hr"); //将<hr/>替换为<br/>
ii.复制元素
如上所述,若是插入的元素已是文档的一部分,这些元素只会简单地移动而不是复制到新位置。若是元素到插入不止一个位置,jQuery在须要时会复制元素,可是当只插入一个位置时,是不会进行复制操做的。若是想复制元素到新位置而不是移动它,必须首先用clone()建立并返回每个选中元素(包含元素全部子孙)的一个副本。clone()建立并返回一个选中元素(包含元素全部子孙)的一个副本。返回的jQuery对象的元素还不是文档的一部分,能够用上一节的方法将其插入文档中。
//给文档结尾添加一个带有"linklist" id的新div $(document.body).append("<div id = 'linklist'><h1>List of Links</h1></div>"); //将文档中全部连接复制并插入新div中 $("a").clone().appendTo("#linklist"); //在每个连接后面插入<br/>元素,使其独立行显示 $("#linklist > a").after("<br/>");
clone()不会复制事件处理程序(见第4节)和与元素相关联的其它数据(2节iiiiiii)。若是想复制这些额外的数据,请传入true参数。
iii.包装元素
插入HTML文档的另外一只类型涉及在一个或多个元素中包装新元素。jQuery定义了3个包装函数。wrap()包装每个选择元素。wrapInner()包装每个选中元素的内容。wrapAll()则将选中元素做为一组数组来包装。这些方法一般传入一个新建立的包装元素或用建立新包装元素的HTML字符串。若是须要,HTML字符串能够包含多个嵌套元素,但必须是单个最内层的元素。若是传入函数给这些方法,它会在每一个元素的上下文中调用一次,this指向该元素,元素的索引值是惟一参数,应该返回须要返回表示包装元素的字符串、Element或jQuery对象。下面是些例子:
//用<i>元素包装全部<h1>元素 $("h1").wrap(document.createElement("i")); //=> <i><h1></h1></i> //包装全部<h1>元素的内容,使用字符串参数更简单 $("h1").wrapInner("<i/>") //=> <h1><i>1</i></h1> // 将第一个段落包装在一个锚点和div里 $("body>p:first").wrap("<a name='lead'><div class='first'></div></a>"); // 将全部其它段落包装在另外一个div里 $("body>p:not(:first)").wrapAll("<div class='rest'></div>");
iiii.删除元素
除了插入和替换操做,jQuery还定义了用来删除元素的方法。empty()会删除每一个选中元素的全部子节点(包括文本节点),但不会修改元素自身。对比而言,remove()方法会从文档中移除选中元素(以及 元素的全部的 内容。)一般不带参数调用remove(),此时会从文档中移除jQuery对象中的全部元素。然而,若是传入一个参数,该参数会被当成选择器,jQuery对象中只有匹配该选择器的元素才会被移除。(若是只想将元素从选中元素集中移除,而不须要从文档中移除时,请使用filter()方法,该方法会在8.ii中讲述)注意,将元素从新插入文档钱,移除操做是不必的:简单地将其插入新的位置,就会移除他们。
remove()方法会移除全部的时间处理程序(参加4节)以及绑定到元素上的其它数据(2.iiiiiii)。detach()方法和remove()相似,但不会移除事件处理程序和数据。想临时从文档中移除元素以便后续再插入时,detach()可能会更有用。
最后,unwarp()方法能够用来实现元素的移除,其方式是wrap()或wrapAll()方法的反操做:移除每个选中元素的父元素,不影响选中元素及兄弟节点。也就是说,对于每个选中的父元素,它替换改元素的父节点为父节点的子节点。与remove()和detach()不一样,unwrap()不接受可选的选择器参数。
4.使用jQuery处理事件
在15章咱们知道,处理事件时有一个难点是IE(IE9如下),实现了一个与其余浏览器不一样的事情API,为了解决这一难点,jQuery定义了一个统一事件API,可工做在全部的浏览器中。jQuery API更具简单的形式,比标准或IE的事件API更易使用。jQueryAPI还更具备复杂,功能齐全的形式,比标准的API更强大。接下来章节咱们会更详细阐述。
i.事件处理程序的简单注册
jQuery定义了简单的事件注册方法,可用于经常使用和普通的每个浏览器事件。好比,给单击事件注册一个处理程序,只须要调用click()方法:
$("p").click(function(){$(this).css("background-color","gray");});
调用jQuery的事件注册方法能够给全部选中元素注册处理程序。很明显,这笔addEventListener()或attachEvent()一次注册一个程序简单不少。
下面是jQuery定义的简单的事件处理程序注册的方法:
blur() | focusin() | mousedown() | mouseup() |
change() | focusout() | mouseenter() | resize() |
click() | keydown() | mouseleave() | scroll() |
dbclick() | keypress() | mousemove() | select() |
error() | keyup() | mouseout() | submit() |
focus() | load() | mouseover() | unload() |
这些注册方法大部分都用于在第15章已经熟悉的常见事件类型。下面按顺序给出了一些注意事项。focus和blur事件不支持冒泡,但focusin和focusout支持,jQuery确保这些事件在全部的浏览器下都支持。相反地,mouseover和mouseout事件支持冒泡 ,但这常常不方便,由于很难知道鼠标是从本身感兴趣的元素移开了,还只是从改元素的子孙元素移开了。mouseenter和mouseleave是非冒泡事件,能够解决刚才的问题。这几个事件类型最初是IE引入的,jQuery保证它们在全部的浏览器下正常工做。
resize和unload事情类型只在Window对象中触发,若是想要给这两个事件类型注册处理程序,应该在$(window)上调用resize()和unload()方法。scroll()方法常常也用$(window)对象上,但它也能够用在有滚动条的任何元素上(好比,当css的overflow属性设置为scroll或"auto"时)。load()方法能够在$(window)上调用,用来给窗口加载事件处理程序,但常常更好的选择是,直接将初始化函数传给1.i所示的$()。固然,还能够在iframe和图片上使用load()方法。注意,用不一样的参数调用时,load()方法能够用在<img>元素上,用来注册当图片加载失败时的调用程序。error()不该该用于设置12章6节描述的窗口onerror属性
除了这些简单的事件注册方法外,还有两个特殊形式的方法,有时颇有用。hover()方法用来给mouseenter和mouseleave事件注册处理程序。调用hover(f,g)就和调用mouseenter(f),而后调用moseleave(g)同样。若是仅传入一个参数给hover(),该参数函数会同事用作enter和leave事件的处理程序。
另外一个特殊事件注册方法是toggle()。该方法将事件处理程序函数绑定到单击事件。可指定两个或多个处理程序函数,当单击事件发生时,jQuery每次会调用一个处理程序函数。例如,若是调用toggle(f,g,h),第一次单击时触发f(),第二次会调用g(),第三次调用会h(),而后调用f()来处理第四次单击事件。当心使用toggle():咱们将在5.i看到,该方法能够用来显示或隐藏选中的元素(也就是说:切换选中元素的可见性)。
4节iiii中,咱们会用到其它更通用的方式来注册事件处理程序,本节最后,让咱们学习一个更简单更便捷的处理程序注册方法。
回忆下,能够传递HTML字符串给$()方法来建立该字符串所描述的元素,还能够传入一个对象(当作第二个参数),该对象由属性组成,这些属性能够设置到新建立的元素上。这第二个参数能够是传递给attr()方法的任意对象。此外,若是这些属性中有任何一个与上面举例的事件注册方法同名,该属性值就会看成处理程序函数,并注册命名事件类型的处理程序。例如:
$("<img />", { src: img_url, alt: img_description, className: "trans_img", click: function() { $(this).css("opacity", "50%"); } });
ii.jQuery事件处理程序
上面例子中事件处理程序函数被当作不带参数以及不返回值的。像这样书写事件处理程序很是正常,但jQuery调用每个事件处理程序时的确传入了一个或多个参数,而且对处理程序的返回值进行了处理。须要知道的最重要的一件事情是,每一个事件处理程序都传入一个jQuery事件对象做为第一个参数。该对象的字段提供了与该事件相关的详细信息(好比鼠标的指针坐标)标准事件的的属性在第15章描述过。jQuery模拟标准Event对象,即使在不支持的标准事件对象的浏览器中(像IE8及其如下),jQuery事件对象在全部的浏览器拥有一组相同的字段。在这4.iii节会详细描述
一般,调用事件处理程序时只带有事件对象这个惟一参数,若是用tigger()(参见4.iiiii)显式触发事件,能够传入额外的参数数组。这样作时,这些参数会在第一个事件对象参数以后传递给事件处理程序。
无论他们是如何注册的,jQuery事件处理程序函数的返回值始终有意义。若是处理程序返回false,与该事件相关联的默认行为,以及该事件接下来的冒泡都会被取消,也就是说,返回false等同调用Event对象的preventDefault()和stopPropagation()方法。一样,当事件处理程序返回一个值,(非undefined值)时,jQuery会将该值存储在Event对象的result属性中,该属性能够被后续调用的事件处理程序访问。
iii.jQuery事件对象
jQuery经过定义本身的Event对象来隐藏浏览器之间的实现差别。当一个jQuery事件处理程序被调用时,总会传入一个jQuery事件对象做为其第一个参数。jQuery事件对象主要以W3C标准为基础,同时它实现了一些实际的事件标准。jQuery会将如下全部字段从原生Evenet对象中复制到jQuery Event对象上(尽管对于特定事件类型来讲,有些字段为undefined)
altKey | ctrlKey | newValue | screenX |
attrChange | currentTarget | offsetX | sceenY |
attrName | detail | offsetY | shiftKey |
bubbles | eventPhase | origainaTarget | srcElement |
button | formElement | pageX | target |
cancelable | keycode | pageY | toElement |
charCode | layerY | relateNode | wheelData |
clientX | layerY | relateNode | wheelDelta |
clientY | metaKey | relatedTarget | which |
除了这些属性,Event对象还定义了如下方法
preventDefault() | isDefauletPrevented |
stopPropagation | isPropagationStopped |
stopImmediatePropagation | isImmediatePropagationStopped |
这些事件和属性和方法大部分在第15章介绍过,而且在第四部分ref-Event中有详细的文档说明。对于一部分字段,jQuery作了特殊处理,使其再全部浏览器中行为一致,值得咱们留意:
metaKey
若是原生事件对象没有metaKey属性,jQuery会使其与ctrlKey属性的值同样。在Mac os中,Command键设置meta键的属性
pageX和pageY
若是 原生事件对象没有定义这两个属性,但定义了鼠标指针的视口坐标clientX和clientY,jQuery会计算出鼠标指针的文档坐标并把他们存储在pageX和pageY中。
target,currentTarget,relatedTarget
target属性表示在其上发生事件的元素文档。若是原生事件对象的目标是文本节点,jQuery返回的目标会替换为包含文本节点的元素。currentTarget是当前正在执行的事件处理程序所注册的元素,与this应该始终同样。
若是currentTarget和target不同,那么正在处理的事件是从触发它的元素冒泡上来的,此时使用is()方法来检测target元素可能会颇有用。
if($(event.target).is("a")) return; //忽略在连接上启动的事件
涉及mouseover和mouseout等过渡事件时,relatedTarget表示其余元素。例如,对于mouseover事件,relatedTarget属性指鼠标指针移开的元素,target则是鼠标指针悬浮的元素。若是原生事件对象没有定义relatedTarget但定义了toElement和formElement,则会从这些属性中获得relatedTarget.
timeStamp
事件发生时的时间,单位是毫秒,有Data.getTime()方法返回。这个字段是jQuery自身设置的,能够解决fireFox中长期存在的一个bug
which
这是一个非标准事件属性,jQuery作了统一化处理,使其能够用来指明在事件发生起见,按下的是那个鼠标按键或键盘按键。对于键盘事件来讲,若是原生事件没有定义which,但定义了charCode或keyCode,which将被设置为定义过的charCode或keyCode。对于鼠标事件来讲,若是which没有定义但定义了button属性,会根据button的值来设置which。0表示没有按钮按下。1表示鼠标左键按下,2表示鼠标中键按下,3表示鼠标右键按下。(注意:单击鼠标右键时,有些浏览器不会产生鼠标事件)
此外,jQuery Event对象的如下对象的字段是特定于jQuery添加的,有时会颇有用。
data
若是注册事件处理程序时指定了额外的数据(参加17.4.iiii),处理程序能够用该字段值来访问。
handler
当前正在被调用的事件处理程序函数的引用
result
该事件最近调用的处理程序的返回值,忽略没有返回值的处理程序
originalEvent
浏览器上生成的原生事件对象的引用。
iiii.事件处理程序的高级注册
咱们已经看到,jQuery定义了至关多简单的方法来注册事件处理程序。这些方法都是简单地调用单一的、更复杂的方法bind()来为命名事件类型绑定处理程序,该处理程序会绑定到jQuery对象中的每个元素上。直接使用bind()可让咱们使用事件注册的高级特性,这些特性在较简单的方法是不能够用的。(jQuery使用术语"bind"来表示事件注册处理程序的注册。ECMAScript5(以及很多javascript框架)给函数定义了bind()方法,参见8.7.iiii,使用"bind"术语表示对象与函数之间的关联,这些函数会在这些对象上调用。Function.bind()方法的jQuery版本是一个名为jQuery.proxy()的工具函数,咱们在本章第7节中会讲解它)
在最简单的形式下,bind()须要一个事件类型字符串做为其第一个参数,以及一个事件处理程序函数做为第二个参数。事件注册的简单方法使用该形式的bind()。例如,调用$('p').click(f)等价
$("p").bind('click',f);
调用bind()时还能够带有第三个参数。在这种形式下,事件类型是第一个参数,处理程序是第三个参数。在这两个参数之间能够传入任何值,jQuery会在调用处理程序钱,将指定的值设置为Event对象的Data属性。经过这些方法传递额外的数据给处理程序,不要使用闭包,有时颇有用。
bind()还有其它高级特性,若是第一个参数是由空格分隔的事件类型列表,则处理程序函数会为每个命名的时间类型注册。例如,调用$("a").hover(f),等同于
$("a").bind('mouseenter mouseleave',f)
bind()的另一个重要特性是容许为注册的事件处理程序指定命名空间。这使得能够定义处理程序组,能方便后续或卸载特定命名空间下的处理程序。处理程序的命名空间对于开发者可服用jQuery代码的类库或模块对程序员来讲特别有用。事件命名空间相似css的类选择器。要绑定事件处理器到命名空间时,添加句点(.)和命名空间名到事件类型字符串中便可:
//做为mouseover处理程序在命名空间"myMode"中把f绑定到全部元素 $('a').bind('mouseover.myMod', f);
甚至还能够给处理程序分配多个命名空间,以下所示:
//在命名空间"myMode"和"yourMod"中做为mouseout处理程序绑定f $("a").bind("mouseout.myMod.yourMod",f)
bind()的最后一个特性是,第一个参数能够是对象,把该对象事件名映射处处理程序函数。再次使用hover()方法举例,调用$("a").hover(f,g)等价于
$("a").bind({mouseenter:f,mouseleave:g});
当使用bind()的这种形式时,传入对象的属性名能够是空格分隔的事件类型的字符串,也包括命名空间。若是在第一个对象参数以后还指定了第二个参数,其值会用作每个事件绑定的数据参数。
jQuery还有另一个事件处理程序注册的方法。调用one()方法就和bind()同样,两者的工做原理也相似 ,处理在调用事件处理程序以后会自动注销它。这意味着,和该方法名字暗示同样,使用one()注册的事件处理器永远只会触发一次。
使用addEventListener()参见15章2.iii能够注册捕获事件处理程序,bind()和one()没有该特性。IE(IE9如下版本)不支持捕获处理程序,jQuery不打算模拟该特性。
iiiii.注销事件处理程序
使用bind(或任何更简单的时间注册方法)注册事件处理程序后,可使用unbind()来注销它,以免在未来的事件中触发它。(注意,unbind()只注销用bind()和相关jQuery方法注册的事件处理程序。经过addEventListener或IEattachRvent()方法注册的处理器不会被注销,而且不会移除经过onclick和onmouseover等元素属性定义的处理程序。)不带参数时,unbind()会注销jQuery对象中全部元素的(全部事件类型的)全部事件处理程序:
$("*").unbind();//从全部元素中移除全部jQuery事件处理程序
带有一个字符串参数时,由该字符串指明事件类型(能够是多个,当字符串包含有多个名字时)全部处理程序会从jQuery对象的全部元素中取消绑定:
//从全部a元素中取消全部mouseover和mouseout处理程序 $("a").unbind("mouseover mouseout");
这是很粗略的方法,不该该在模块化代码中使用,由于模块的使用者有可能使用其余模块,在其余模块中有可能在相同的元素上给相同的事件类型注册了其它处理程序。若是模块使用命名空间来注册事件处理程序,则可使用unbind(),传入一个参数,来作到只注销命名空间下的处理程序:
//取消绑定在mymode命名空间下全部mouseover和mouseout处理程序 $("a").unbind("mouseover.myMode mouseout.myMod"); //取消绑定在"myMod"命名空间下的全部事件类型处理程序 $("a").unbind(".myMod") //取消绑定在ns1和ns2命名空间下的单击处理程序 $("a").unbind("click.ns1.ns2")
若是想当心地只取消绑定本身的事件处理程序,但没有使用命名空间,必须保留事件处理程序函数的一个引用,并使用unbind()带两个参数的版本。在这种形式下,第一个参数是事件类型字符串(不带命名空间),第二个参数是处理程序函数:
$("#mybutton").unbind("click",myClickHandler);
使用这种方式调用时,unbind()从jQuery对象的全部元素中注销特定类型的指定事件处理程序函数。注意,即便使用有3个参数的bind()经过额外的数据值注册事件处理程序,也可使用有两个参数的unbind()事件来取消绑定它们。
能够传递单一对象参数给unbind()。在这种状况下,unbind()会轮询为该对象的美怡属性调用一次。属性名会用作事件类型字符串,属性值会用作处理程序函数:
$("a").unbind({
mouseover:onmouseoverHandler,
mouseout:onmouseoutHandler
});
最后,还有一种方式来调用unbind()。若是传递一个jQuery Event对象给unbind(),它会取消绑定传入事件的处理程序,调用unbind(ev)等价于unbind(ev.type,eb.handler)。
iiiiii.触发事件
当用户使用 鼠标、键盘或触发其它事件类型时,注册的事件处理程序会自动调用。然而,若是能手动触发事件,有时会颇有用。手动触发事件最简单的方式是不带参数调用事件注册的简单方法(好比click()或mouseover()).与不少jQuery方法能够同时getter和setter同样,这些事件方法在带有一个参数时会注册事件处理程序,不带参数调用时则会触发事件处理程序。例如:
$("#my_form").submit();// 就和用户单击提交按钮同样
上面的submit()方法本身合成了一个Event对象,并触发了给submit事件注册的全部事件处理程序。若是这些事件处理程序都没有返回false或调用Event对象的preventDefault(),事件上将提交改表单。注意,经过这种方式手动调用时,冒泡事件依旧会冒泡。这意味这触发一组选中元素事件,同时也会触发这些元素祖先节点的处理程序。
须要特别注意:jQuery的事件触发方法会触发全部使用jQuery事件注册方法注册的处理程序,也会触发经过onsubmit等HTML属性或Element属性定义的处理程序。可是,不能手动触发使用addEventListener()或attachEvent()注册的事件处理程序(固然在真实时间触发时,这些处理程序依旧会调用)
同时须要注意的,jQuery的时间触发机制是同步的--不涉及事件队里。当触发一个事件时,在调用的触发方法返回以前,事件处理程序会马上调用。若是触发了一个单机事件,被触发的处理程序又触发了一个submit事件,全部匹配的submit处理程序会调用下一个单机处理器以前调用。
绑定和触发事件时,submit()这种方法会很便捷,但就如jQuery定义了一个更通用的bind()方法同样,jQuery也定义了一个更通用的trigger()方法。一般,调用triggter()时会传入事件类型字符串做为第一个参数,trigger()会在jQuery对象中的全部元素上触发为该类型事件注册的全部处理程序。所以,上面的submit()调用等价于:
$("my_form").trigger("submit");
与bind()和unbind()方法不一样,在传入的字符串中不能指定多个事件类型。然而,与bind()和unbind()同样的是,能够指定事件命名空间来触发仅在该命名空间中定义的处理程序。若是只想触发没有命名空间的事件处理程序,在事件类型后添加一个感叹号就行。经过onclick等属性注册的处理程序被认为是没有命名空间的:
$("button").trigger("click.ns1"); // 触发某个命名空间下的单击处理程序 $("button").trigger("click1"); // 触发没有命名的单击处理程序
除了给trigger()传入事件类型字符串做为第一个参数,还能够传入Event对象(或任何由type属性的对象)。type属性会用来判断触发什么类型的处理程序。若是传入的是jQuery事件对象,该对象会传递给触发的处理程序。若是传入的是普通对象,会建立一个新的jQuery Event对象,普通对象的属性会添加到新对象中。这样,能够很容易传递额外数据给事件处理程序:
//button1的事件处理程序触发button2上的相同的时间 $("#button1").click(function(e){$("#button2").trigger(e);}); // 触发事件时,添加额外的属性给事件对象 $("#button1").trigger({type:"click",synthetic:true}); // 该处理程序检测额外属性来区分是真实时间仍是虚假事件 $("#button1").click(function(e){ if (e.syntheic) {...}; });
给事件处理程序传递额外数据的另外一种方式是,在手动触发事件时,给trigger()传入第二个参数。给trigger()传入的第二个参数会成为每一个触发事件处理程序的第二个参数。若是传入数组做为第二个参数,数组的每一项会做为独立参数传递给触发的处理程序:
$("#button1").trigger("click",true); //传入单一额外参数 $("#button1").trigger("click",[x,y,z]);//传入三哥额外的参数
有时,会想触发给定事件类型的全部处理程序,而无论这些处理程序是绑定到什么文档元素上的。这时可使用$('*')来选中全部元素,而后对调用trigger(),但是这样作很是低效。更好的方是,使用jQuery.event.trigger()工具函数,来全局触发事件。该函数接受参数和trigger()方法同样,但在整个文档中触发指定事件类型的事件处理程序时更高效。注意,以这种方式触发的“全局事件”不会冒泡,而且只会触发使用jQuery方法注册的处理程序(不包括onclick等DOM属性注册的事件处理程序)。
trigger()(及调用它的便捷方法)在调用事件处理程序后,会执行与触发事件相关联的默认操做(假设事件处理程序没有返回false或调用事件对象的preventDefault())。例如,触发一个<form>元素的submit事件,trigger()会调用该表单的submit()方法,若是触发一个元素的focus事件,tigger()会调用元素的focus()方法。
若是想调用事件处理程序,但不调用默认操做,可使用triggerHandler()替代trigger()。该方法和trigger()类型,除了首先会调用Event对象的preventDefault()和cancelBubble()方法。这意味着经过triggerHandler()手动触发的事件不会冒泡,也不会执行相关联的默认操做。
iiiiiii.自定义事件
jQuery的事件管理体系是为标准事件而设计的,好比web浏览器产生的鼠标单击和按键按下。可是,jQuery不限于这些事件,你可使用任何想用的字符串来做为事件类型名称。使用bind()能够注册这种“自定义事件”的处理程序,使用trigger()能够调用这些处理程序。
对于书写模块化代码,实现发布/订阅模型或观察者模式时,这种自定义处理程序的间接调用被证实是很是有用的。使用自定义事件时,一般你会发现,使用jQuery.event.trigger()函数替代trigger()来全局触发处理器会更有用。
// 用户单击"logoff"按钮是,广播一个自定义事件 // 给任何须要保存状态的感兴趣的观察者,而后导航到logoff页面 $("#logoff").click(function(){ $.event.trigger("logoff"); //广播一个事件 window.location = "logoff.aspx"; //导航到新页面 });
在6.iiii节咱们将看到jQuery的ajax方法会像上面这样广播自定义自定义事件,以通知感兴趣的监听器。
iiiiiiii.实时事件
bind()方法绑定事件处理程序到指定的文档元素,就与addEventListner()和attachEvent()(参见第17章)同样。可是,使用jQuery的web应用常常动态建立新元素。若是使用bind()给文档中的全部<a>绑定了事件处理程序,接着又建立了带有<a>元素的新文档内容,这些信元素和老元素不会拥有相同的事件处理程序,其行为将不同。
jQuery使用“实时事件”来解决这一问题。要使用实时事件,须要使用delegate()和undelegate()来替代bind()和unbind()。一般,在$(document)上调用delegate(),并传入一个jQuery选择器字符串、一个jQuery事件类型字符串以及一个jQuery事件处理程序函数。它会在document或window上(或jQuery对象中的任何元素上)注册一个内部处理程序。当指定类型的事件冒泡到该内部处理程序时,它会判断事件目标(该事件所发生在的元素)是否匹配选择器字符串。若是匹配,则调用指定的处理程序函数。所以,为了同时处理老的和新建立的<a>元素上的mouseover事件,可能须要下面这样注册处理程序:
$(document).delegate("a","mouseover",linkHandler)
不然,须要使用bind()来处理文档中的静态部分,而后使用delegate()来处理动态修改的部分:
//静态连接的静态事件处理程序 $("a").bind("mouseover",linkHandler); //文档中动态更新的部分使用实时事件处理程序 $(".dynamic").delegate("a","onmouseover",linkHandler);
与bind()方法拥有三个参数版原本指定事件对象的data属性同样,delegate()方法拥有4参数版本用来干一样的事情。使用这种版本时,将数据值做为第三参数传入,处理程序函数则做为第4参数。
理解这点很重要:实时事件依赖于事件冒泡。当事件冒泡到document对象时,它有可能已经传递给不少静态事件处理程序。若是这些处理程序中有任何一个调用了Event对象的cancalBubble(),实时事件处理程序将永远不会调用。
jQuery定义了一个名为live()的方法,也能够用来注册实时事件,live()比delegate()更难理解一些,但与bind()同样,live()也有两参数和三参数的调用形式,而且在实际中用得更广泛。上面对delegate()的两个调用,也能够用live()来写 ,以下所示:
$("a").live("mouseover",linkHandler);
$("a",$(".dynamic")).live("mouseover",linkHandler);
在jQuery对象上调用live()方法时,该对象中的元素实际上并无使用。真正有关系的是用来建立jQuery对象的选择器字符串和上下文对象(传递给$()的第一个和第二个参数)。jQuery对象的context()和selector属性来使得这些值可用。(见本章1.ii内容)一般,仅带一个参数的调用$()时,context是当前文档 。所以,对于jQuery对象x,下面两行代码作的事情是同样的:
x.live(type,Handler);
$(x.context).delegate(x.selector,type,handler);
要注销实时处理程序,使用die()或undelegate()。可用带一个或两个参数调用die()。带有一个事件类型参数时,die()会移除匹配选择器和事件类型的全部实时事件处理程序。带有事件类型和处理程序函数参数时,它只会移除掉指定的处理程序。一些例子:
$("a").die('mouseover'); //移除<a>元素上的mouseover事件的全部实时处理程序 $("a").die("mouseover",linkHandler); //移除一个指定的实时处理程序
undelegate()相似die(),但更显式地分开context(内部事件处理程序所注册的元素)和选择器字符串。上面的die()的调用能够写成下面这样
$(document).undelegate('a'); //移除<a>元素上面的全部实时处理程序 $(document).undelegate('a','mouseover'); //移除mouseover的实时处理程序 $(document).undelegate('a','mouseover',linkHandler); //移除指定处理程序
最后,undelegate()也能够不带任何参数调用。在这种状况下,它会注销从选中元素委托的全部实时事件处理程序。
5.动画效果
第14章展现了如何经过脚原本修改文档的css样式。例如,经过设置css的visibility属性,能够显示和隐藏元素。14.3.i节进一步演示了如何经过脚本控制css来产生动画视觉效果。例如,除了仅让一个元素消失,还能够在半秒内逐步减小opacity属性的值,使其快速淡出,而不是瞬间消失。这些动画视觉效果能给用户带来更愉悦的体验,jQuery使其实现起来更简单。
jQuery定义了fadeIn()和fadeOut()等简单方法来实现常见的视觉效果。除了简单的动画方法,jQuery还定义了一个animate()方法,用来实现更复杂的自定义动画。下面将讲述这些简单动画方法,以及更通用的animate()方法。首先,让咱们了解下jQuery动画框架的一些通用 特性。
每段动画都有时长,用来指定动画效果执行多长时间。可使用毫秒数值或字符串来指定时长。字符串"fast"表示200ms。字符串"slow"表示600ms。若是指定的字符串时长jQuery没法识别,则采用默认时长400ms。能够给jQuery.fx.speeds添加新的字符串到数值映射关系来定义新的时长名字:
jQuery.fx.speeds["medium-fast"] = 300;
jQuery.fx.speeds["medium-slow"] = 500;
jQuery动画方法常用动画时长来做为可选的第一个参数。若是省略时长参数,一般会获得默认值400ms。注意,省略时长时,有部分方法会马上跳到最后一帧,没有中间的动画效果:
$("#message").fadeIn(); //用淡入的效果显示元素,持续400ms $("#message").fadeOut("fast");//淡出的效果隐藏元素,持续200ms
禁用动画
在不少网站上,动画视觉效果已经成为标配,可是,并非全部用户都喜欢:有些用户以为动画分散注意力,有些则感受动画致使操做不便,残障用户可能会发现动画会妨碍屏幕阅读器等辅助软件正常工做,老旧硬件用户可能以为耗费不少cpu时间。为了对用户保持村长,咱们一般应该让动画朴素简单,并提供一个选项能够完全禁用动画。使用jQuery能够很是简单的全局禁用全部动画:简单的设置jQuery.fx.off为true便可。该设置会将每段动画的时长都变成0ms.这样动画就行是没有动画的马上切换了。
为了最终用户能够禁用动画,能够在脚本上使用以下代码:
$(".shoping").click(function(){jQuery.fx.off = true;});
这样,当网页设计者在页面中加入带有"shoping"类的元素时,用户就能够单击该元素来禁用动画。
jQuery动画是异步的。调用fadeIn()等动画方法时 ,它会马上返回,动画在“后台”执行。因为动画方法会在动画完成以前返回,所以能够向不少jQuery动画方法传入第二个参数(也是可选的),该参数是第一个函数,会在动画完成时调用。该函数在调用时不会有任何参数传入,但this值会设置为发生动画的文档元素。对于每一个选中元素都会调用一次该回调函数:
//用淡入效果快速显示元素,动画完成时,在元素里显示一些文字 $("#message").fadeIn("fast",function(){ $(this).text("Hello world"); });
给动画传入回调函数,能够在动画结束时执行操做。不过,若是只是想顺序执行多段动画的话,回调方式是没有必要的。jQuery动画默认是队列话的(5.ii节下面的“动画选项对象”节会讲述如何覆盖默认方式)。若是一个元素已经在动画过程当中,再调用一个动画方法时,新动画不会马上执行,而会延迟到当前动画结束后才执行。例如,可让一个元素在持久显示前,先闪烁一阵:
$("#message").fadeIn(100).fadeOut(100).fadeIn(100).fadeOut(100).fadeIn();
jQuery动画方法能够接受可选的时长和回调参数。还能够传入一个对象来调用动画方法,该对象的属性指定动画选项:
// 将时长和对调参数做为对象的属性而不是参数传入 $("#message").fadeIn({ duration:"fast", complete:function(){ $(this).text("Hello World"); } });
使用通用的animate()方法时,常常传入选项对象做为参数,其实,这也能够用于更简单的动画方法。使用选项对象能够设置高级选项,好比控制动画的队列和缓动。5.ii节下面的“动画选项对象”节会讲述可用的选项。
i.简单动画
jQuery定义了9个简单动画方法用来隐藏和显示元素。根据实现的动画类型,它们能够分为三组:
fadeIn(),fadeOut(),fadeTo()
这是最简单的动画,fadeIn()和fadeOut()简单改变CSS的opacity属性来显示或隐藏元素。二者都接受可选的时长和回调参数。fadeTo()稍有不一样:它须要传入一个opacity的目标值,fadeTo()会将元素的当前opacity值变化到目标值。调用fadeTo()方法是,第一个参数必须是时长(或选项对象),第二参数是opacity目标值,回调函数则是可选的第三个参数。
show()、hide()、toggle()
上面的fadeOut()方法可让元素不可见,但依旧保留了元素在文档布局中的占位。hide()方法将元素从布局中移除,就好像把CSS的display属性设置为none同样。当不带参数调用时,hide()和show()方法只是简单地隐藏或显示选中元素。带有时长(或选项对象)参数时,他们会让隐藏或显示有个动画过程。hide()在将元素的opacity减小到0时,同时它还将元素的宽度和高度收缩到0,show()这进行反向操做。
toggle()能够改变在上面调用它的元素的可视状态:若是隐藏,则调用show();若是显示,则调用hide()。与show()和hide()同样,必须传入时长或选项对象给toggle()来产生动画效果。给toggle()来产生动画效果。给toggle()传入true和不带参数调用show()是同样的,传入false则和不带参数调用的hide()是同样的。注意,若是传入两个或多个参数给toggle(),它会注册为事件处理程序。这在4.i小节讲述过。
slideDown()、sildeUp()、slideToggle()
slideUp()会隐藏jQuery对象中的元素,方式是将高度动态变化到0,而后设置CSS的display的属性为"none"。slideDown()执行反向操做,来是的隐藏的元素再次可见。slideToggle()使用向上滑动或向下滑动动画来切换元素的可见性。这三个方法都接受可选的时长和回调参数(或选项对象参数)。
下面是一个例子,它调用了改组方法中的每个。要记得jQuery动画默认状况下是队列化的,依次这些动画会一个接一个的执行:
//用淡出效果将全部图像隐藏,而后显示他们,接着向上滑动,在向下滑动 $("img").fadeOut().show(300).slideUp().slideToggle();
各类jQuery插件(参加第9节)会添加额外的动画方法到jQuery类库中。jQuery UI类库(参见10节)拥有一套特别全面的动画效果。
ii.自定义动画
与简单动画方法实现的效果相比,使用animate()方法能够实现更多通用动画效果。传给animate()方法的第一个参数指定动画内容,剩余参数指定如何定制动画。第一个参数是必须的:它是一个对象,该对象的属性指定要变化的CSS属性和他们的目标值。animate()方法会将每一个元素的这些CSS属性从初始值变化到指定的目标值。例如上面描述的slideUp()效果能够用如下代码来实现:
//将全部的图片高度缩小到0 $("img").animate({height:0})
第二个参数是可选的,能够传入一个现象对象给animate()方法:
$("#message").animate({ opacity:0.25, fontSize:10 },{ duration:500, //动画持续半秒 complete:function(){ //动画完成后执行该函数 console.log("end!"); } });
除了让选项对象做为第二个参数传入,animate()方法还容许将三个最经常使用的选项做为参数传入。能够将动画时长(数值或字符串)做为第二个参数传入。能够指定缓动函数做为第三个参数。(很快就会讲解缓动函数)最后能够将回调函数指定为第三个参数。
一般,animate()方法接受两个对象参数。第一个指定动画内容,第二个指定如何定制动画。要完全理解如何使用jQuery来实现动画,还须要弄明白这两个对象的更多细节。
⑴动画属性对象
animate()方法的第一个参数必须是对象。该对象的属性名必须是CSS属性名,这些属性的值必须是动画的目标值。动画只支持数值属性:对于颜色,字体或display等枚举属性是没法实现动画效果的(jQuery的实现方式不支持非数值动画,但有其它实现方案,好比传入自定义的CSS属性变化函数)。若是属性是数值,则默认单位是像素。若是属性值是字符串,能够指定单位,若是省略单位,则默认依旧是像素。还能够指定相对值,用"+="前缀表示增长,或用"-="表示减小。例如:
$("#message").animate({ "margin-left": "+=40", "opacity":"-=.8" });
注意上面的对象字面量中属性名“margin-left”两旁引号的使用。属性名中的连字符表示不是一个合法的javascript标识符,因此必须用引号括起来 ,固然jQuery也容许使用marginLeft这种大小写混合的写法。
除了数值(能够带有单位、“+=”或"-="前缀),在jQuery动画属性对象中可使用其余三个值,“hide”值会保存属性的当前值,而后将属性值变化到0。“show”值会将css属性的值还元到以前保存的值,jQuery会在动画完成时调用show()方法。若是一段动画使用了"hide",jQuery会在动画完成时调用hide()方法。
还可使用"toggle"来实现显示和隐藏,具体效果取决于该属性的当前设置。能够用下面的代码实现"slideRight"效果(和slideup()方法相似,只是动画内容是元素宽度):
$("img").animate({ width:"hide", borderLeft:"hide", borderRight:"hide", paddingLeft:"hide", paddingRight:"hide" })
将上面的属性值替换为"show"或“toggle”,就能够产生水平滑动的伸缩效果。相似slideDown()和slideToggle()效果。
⑵动画选项对象
animate()方法的第二个参数是可选的,该选项对象来指定动画如何执行。有两个最重要的选项咱们已经接触过,duration属性指定动画效果的持续时间,该属性的值还能够是"fast"、“slow”或任何在jQuery.fx.speeds中定义名称
另一个接触过的选项是complete属性:它指明在动画完成时的回调函数。和complete属性相似,step属性指定在动画每一步 或每一帧调用的回调函数。在回调函数中,this指向正在连续变化的元素,第一个参数则是正在变化的属性的当前值。
在选项对象中,queue属性指定动画是否须要队列化——是否须要等到全部还没有发生的动画都完成后再执行该动画。在默认的状况下,全部的动画都是队列化的。将queue属性设置为false能够取消队列化。非队列化的动画会马上执行。随后队列化的动画不会等待费队列化的动画执行完成以后才执行。考虑以下代码:
$("img").fadeIn(500) .animate({"width":"+=100"},{queue:false,duration:1000}) .fadeOut(500);
上面的fadeIn()和fadeOut()效果是队列化的,但animate()的调用(在1000毫秒内改变width属性)是非队列化的。这段width动画和fadeIn()效果的开始时间相同。fadeOut()效果会在fadeIn()动画效果完成时开始,它不会等到width动画完成。
缓动函数
实现动画时,时间和动画属性值之间能够是线性关系,这些方式很直接,但不够好。例如,一段时长400ms的动画,在100ms时,动画完成了25% 。在该线性动画中,若是将不透明度从1.0变化到0,(多是一个fadeOut()调用),则在100ms时,不透明度为0.75,然而,事实代表,非线性的动画效果会带来更愉悦的体验。所以,jQuery引入了“缓动函数”,来将基于实际的0-1之间的值。缓动函数会返回一个0~1之间的值。一般,缓动函数传入0时返回0,在传入1时返回1。固然,在0-1之间缓动函数能够是非线性的,这可让动画有加速和减速效果。
jQuery默认的缓动函数是正弦函数:它开始很慢,接着加速,而后再缓慢“缓动”变化到终值。jQuery中的缓动函数有名字。默认的缓动函数名字为“swing”,jQuery还实现了一个线性的缓动函数,名字为"linear"。能够添加自定义缓动函数到jQuery.esaing对象上。
jQuery.easing["squareroot"] = Math.sqrt;
在jQuery UI类库中,有一个“jQuery缓动插件”定义了一套更复杂的缓动函数。
剩余的动画选项和缓动函数有关。选项对象的easing属性指定缓动函数名。jQuery默认使用名为“swing”的正弦函数。若是想让动画线性变化,可使用以下选项:
$("img").animate({"width":"+=400"},{duration:500,easing:"linear"});
除了传入选项对象,duration、easing和complete选项能够指定为animate()方法的参数。所以,上面的代码还能够简写成。
$("img").animate({"width":"+=100"},500,"linear")
最后,jQuery动画框架甚至还容许为不一样的css动画属性指定不一样的缓动函数。这有两种方式来实现,代码实例以下:
//用hide()方法隐藏图片,图片的大小采用线性动画 //不透明则使用默认的"swing"缓动函数 //实现方式一:使用specialEasing选项来指定自定义缓动函数 $("img").animate({width:"hide",height:"hide",opacity:"hide"}, {specialEasing:{width:"linear",height:"linear"}}); //实现方式二:在第一个对象中传入[目标值,缓动函数]数组 $("img").animate({ width:["hide","linear"],height:["hide","linear"],opacity:"hide" });
iii.动画的取消、延迟和队列
jQuery还定义了一些动画和队列相关的方法,咱们须要进一步了解。首先是stop()方法,它用来中止选中元素上的当前正在执行的任何动画。top()方法接受两个可选的布尔值参数。若是第一个参数是true,会清楚该选中元素上的动画队列:除了中止当前动画,还会取消任何等待执行的动画。第一个参数的默认值是false:若是忽略该参数,等待执行的动画不会被取消。第二个参数用来指定正在连续变化的CSS属性是否保留当前值,仍是应该变化到最终目标值。传入true可让他们变化到最终值。传入false(或省略该参数)会让他们保持为当前值
当动画是由用户事件触发时,在开始新的动画前,可能须要取消掉当前或等待执行的任何动画,好比
$("img").bind({ mouseover:function(){ $(this).stop().fadeTo(300,1.0); }, mouseout:function(){ $(this).stop().fadeTo(300,0.5) } });
与动画相关的第二个方法是delay()。这会直接添加一个事件延迟到动画队列中:第一个参数是时长(毫秒为单位的数值或字符串),第二个参数是队列名,是可选的(一般并不须要第二个参数:接下来咱们会解释队列名)。能够在符合动画中使用delay(),代码以下:
// 快速淡出为半透明,等一等,而后向上滑动 $("img").fadeTo(100,0.5).delay(200).slideUp()
在上面的stop()方法例子中,使用mouseover和mouseout事件来变化图片的透明度。能够调整该例子:在开始动画时,添加一个短小的延迟。这样,当鼠标快速滑过图片而不停留时,不会有任何分神的动画产生:
$("img").bind({ mouseover:function(){ $(this).stop(true).delay(100).fadeTo(300,1.0); }, mouseout:function(){ $(this).stop(true).fadeTo(300,0.5) } });
和动画相关的最后一组方法能够对jQuery的队列机制进行底层操做。jQuery队列是按照顺序执行的函数列表。每个队列都与一个文档元素(或者是Document或Window对象)关联,每个元素的队列都与其它元素的队列彼此独立。可使用queque()方法给队列添加一个新函数。当某个函数到达队列头部时,它会自动从队列中去除并调用。当函数被调用时,this指向与队列相关的元素。被调用的函数会传入惟一一个回调函数做为参数。当函数完成运行时,它必须调用回调函数。这能够运行队列中的下一个操做,若是不调用回调函数,该队列会中止运行,剩余的函数将永远不会被调用。
咱们知道,经过给jQuery动画方法传入回调函数,就能够在动画完成后执行一些操做。经过对函数执行队列操做,也可达到这一目的:
//淡入显示一个元素,稍等片刻,设置一些文字,而后变化边框 $("#message").fadeIn().delay(800).queue(function(next){ $(this).text("Hello world"); //显示一些文字 next();//运行队列中的下一项 }).animate({"margin-top":"+=40"});
队列函数中的回调函数参数是jQuery 1.4引入的新特性。对于jQuery类库以前的版本,须要调用dequeque()方法“手动”取消队列中的下一个函数:
$(this).dequeue(); //替代next()方法
若是在队列中什么也没有,调用dequeue()方法不会有任何响应。反之,它则会将队列头部的函数从队列中移除,并调用它。设置的this值和传入的回调函数如上所述。
还有一些笨拙的方式来操做队列,clearQueue()方法来清除队列。给queue()方法传入一个函数组成的数组而不是单一函数时,会用传入的函数数组来替换当前队列。若是在调用queue()方法时,不传入任何参数,则会返回当前队列数组。jQuery还将queue()和dequeue()定义成工具函数。若是想给元素e的队列添加一个工具函数f,可使用如下方法或函数:
$(e).queue(f); //建立一个特有的e的jQuery对象,并调用queue()方法。 jQuery.queue(e,f) //直接调用jQuery.queue()工具函数
最后,特地留下queue()、dequeue()和clearQueue()方法均可以有一个可选的队列名来做为第一个参数。jQuery动画方法使用的队列名是"fx",这是没有指定队列名时默认使用的队列。当想要顺序执行异步操做时,jQuery队列机制很是有用:原来须要给一个异步操做传入回调函数来触发队列中的下一个函数,如今能够直接使用 jQuery队列来管理异步序列。只需传入非"fx"的队列名,并记得队列中的函数不会自动执行。必须显式调用dequeue()方法来运行第一个函数,而后每一步操做在完成时必须把下一个操做从队列中移除。
6.jQuery中的ajax
在Web应用编程技术里,Ajax很流行,它使用HTTP脚本(参考16章)来按需加载数据,而不须要加载整个页面。在如今的web应用中,Ajax技术很是有用,所以,jQuery内置了Ajax工具来简化使用。jQuery定义了一个高级工具方法和四个高级工具函数。这些高级工具都基于一个强大的底层函数:jQuery.ajax()。下面的章节会首先描述这些高级工具,而后而后再详细阐述jQuery.ajax()函数。为了完全的理解高级工具的使用,咱们须要理解jQuery.ajax(),即使可能永远不显式的使用它。
1.load()方法
load()是全部jQuery.ajax()工具中最简单的,向它传入一个URL的内容,而后将内容插入每个选中元素中,替换掉已经存在的内容。例如:
//每一个60秒加载并显示最新的状态报告 setInterval(function(){ $("#status").load("ubd.html"); },60000)
4.i也讲到了load()方法,它用来注册load事件的处理程序。若是传给改方法的第一个参数是函数而不是字符串,则load()方法是事件处理程序注册方法而不是Ajax方法。
若是只想显示被加载文档的一部分,能够在URL后面添加一个空格和一个jQuery选择器。当URL加载完成后,jQuery会用指定的选择器来从加载好的HTML中选取须要显示的部分:
//加载并显示天气遇到的温度部分 $("temp").load("wheather_report.html #temperature");
注意:URL后面的选择器看起来很像片断标识符(url的hash部分)。不一样的是,若是想只插入被加载的文档的选中部分的话,则空格是必须的。
除了必须的URL参数,load()方法还接受两个可选参数。第一个可选参数表示的数据,能够追加到URL后面,或者与请求一块儿发送。若是传入的是字符串,则会追加到URL后面(放在“?”或"&"的后面)。若是传入对象,该对象会被转化为用"&"分隔的name/value对与请求后一块儿发送。(对象转化为字符串的具体细节在6.2节下面的(2).jQuery.getJSON()节中描述)一般状况下,load()方法发送HTTP GET请求,可是若是传入数据对象,则它会发送POST请求。下面是两个例子。
// 加载特定区号的天气预报 $("#temp").load("us_weather_report.html", "zipcode=02134") // 使用对象做为数据,并指导为华氏温度 $("#temp").load("us_weather_report.html",{zipcode:02134,units:"f"})
load()方法的另外一个可选参数是回调函数。当ajax请求成功或未成功,以及(当请求成功时)URL加载完毕并插入选中元素时,会调用该回调函数。若是没有指定任何数据,回调函数能够做为第二个参数传入。不然它必须是第三个参数。在jQuery对象的每个元素上都会调用回调函数,而且每次调用都会传入三个参数:被加载的URL的完整文本内容、状态码字符串,以及用来加载该URL的XMLHTTPRequest对象。其中,状态参数是jQuery的状态码,不是HTTP的状态码,尤为是相似“succes”、“error”和“timeout”的字符串。
jQuery的Ajax状态码
jQuery的全部Ajax工具,包括load()方法,会调用回调函数来提供请求成功或失败的异步消息。这些回调函数的第二个参数是一个字符串,能够取如下值:
"success"
表示请求成功完成
"notmodified"
该状态码表示请求已经正常完成,但服务器返回的响应内容是HTTP 304“Not Modified”,表示请求的URL和上次请求的相同,没有变化。只有在选项中设置ifModified为true时,该状态码才会出现(参考6.iii节下面的“(1)通用选项”节),从jQuery1.4版本开始,认为“notmodified”状态码是成功的,但以前的版本会将其当成错误。
"error"
表示请求没有成功完成,缘由是某些HTTP错误。更多细节,能够检测传入每个回调函数中的XMLHTTPRequest对象的HTTP状态码来获取。
"timout"
若是Ajax请求没有在选定的超时区间内完成,会调用错误回调,并传入该状态码。默认状况下,jQuery的Ajax请求没有超时限定,只有指定了timeout选项(见6.iii节下面的“1.通用选项”节时才能看到改状态码)。
"parsererror"
该状态码表示HTTP请求已经成功完成,但jQuery没法按照指望的方式解析。例如,若是服务器返回不符合格式的XML文档或不符合格式的JSON文本时,就会出现该状态码,注意拼写:“parsererror”,而不是"parseerror"
ii.Ajax工具函数
jQuery的其它Ajax高级工具不是方法,而是函数,能够经过jQuery或$()指教调用,而不是在jQuery对象上调用。jQuery.getScript()加载并执行javascript代码文件。jQuery.getJSON()加载URL,并将其解析为JSON,并将解析结果传递到指定的回调函数中。这两个函数都会调用一个更通用URL获取函数:jQuery.get()。最后,jQuery.post()和jQuery.get()很相似,除了执行的是HTTP POST而不是GET请求。与load()方法同样,全部这些函数都是异步的:在任何数据加载钱他们就会返回调用者,加载结果则经过调用指定的回调函数来通知。
⑴.jQuery.getScript()
jQuery.getScript()函数的第一个参数是javascript代码文件的URL。他会异步加载文件,在加载完成后再全局做用域执行该代码。它能同时适用于同源和跨源脚本:
//从其它服务器动态加载脚本 jQuery.getScript("http://baidu.com/a.js");
也能够传入回调函数做为第二个参数,在这种状况下,jQuery会在代码假值和执行完成后调用一次该回调函数。
//加载一个类库,并在加载完成完成时马上使用它 jQuery.getScript("js/mu.plus.js",function(){ $("div").my_plugin(); //使用加载的类库 });
jQuery.getScript()一般会使用XMLHttpRequest对象来获取要执行的脚本内容。但对于跨域请求(脚本与当前文本不在同样的服务器上),jQuery会使用<script>元素来加载脚本。(参考14.2章小节)。在同源的状况下,jQuery.getScript()函数的返回值也是该XMLHTTPRequest对象。对于跨域请求,不存在XMLHTTPRequest对象,而且返回脚本的内容取不到。在这种状况下,回调函数的第一个和第三个参数是undefined,jQuery.getScript()的返回值也是undefined。
传递给jQuery.getScript()的回调函数,仅在请求成功完成时才会被调用。若是须要在发生错误已经成功时都获得通知,则须要使用底层的jQuery.ajax()函数。该节所描述的其余三个工具函数也是如此。
⑵.jQuery.getJSON()
jQuery.getJSON()与jQuery.getScript相似:它会获取文本,而后特殊处理一下,再调用指定的回调函数。jQuery.getJSON()取到文本后,不会将其当作脚本执行,而会将其解析为JSON(第7节会描述jQuery.parseJSON()函数)。jQuery.getJSON()只有在传入回调函数时才有用。当成功加载URL,以及将内容解析成为JSON后,解析结果会做为第一个参数传入回调函数中。与jQuery.getScript()同样,回调函数的第二个和第三个参数是"success",状态码和XMLHttpRequest对象:
//假设 data.json 包含文本:{"x":1,"y":2} jQuery.getJSON("data.json", function(data) { //data 参数是对象{ x:1,y:2 } });
与jQuery.getScript()不一样,jQuery.getJSON()接受一个可选的数据对象参数,就和传入load()方法中的同样。若是传入数据到jQuery.getJSON()中,该数据必须是第二个参数,回调函数则是第三个。若是不传入任何数据,则回调函数能够是第二个参数。若是数据是字符串,则它会被添加到URL的"?"或"&"后面。若是数据是一个对象,则它会转化为字符串。(参加下面内容),而后添加到URL上
传递数据给jQuery的Ajax工具
jQuery的大多数Ajax方法都接受一个参数(或选项)用来指定与URL一块儿发送给服务器数据,一般,该数据的形式是URL编码,用“&”分隔的名/值对。(这个数据格式就是已知的"application/x-www-form-urlencoded" MIME类型。这相似JSON格式:一种将javascript简单对象与字符串互相转化的格式。)对于HTTP GET请求,该数据字符串会添加到请求 URL后面。对于POST请求,则在全部发送的HTTP请求头后面,当作请求的内容体来发送它。
获取该格式的数据字符串的一种方式是,调用包含表单或表单元素的jQuery对象的serialize()方法。例如,可使用以下代码来调用load()方法提交HTML表单:
$("#submit_button").click(function(event) { $(this.form).load( //经过加载新内容来替换表单 this.form.action, //表单url $(this.form).serialize() //将表单数据附加到URL后面 ); event.preventDefault(); //取消表单的默认提交; this.disabled = "disabled"; //防止屡次提交 });
如果将jQuery ajax函数的数据参数(或选项)设置为对象不是字符串,jQuery一般会调用jQuery.param()将对象转化成字符串,jQuery一般会调用jQuery.param()将对象转化成字符串(除了下面提到的一个异常)。该工具函数会将对象的属性当成名/值对,例如,会将对象{x:1,y:"hello"}转化为字符串"x=1&y=hello"。
若是将jQuery ajax函数的数据参数(或选项)设置为对象不是字符串,jQuery一般会调用jQuery.param()将对象转化成字符串,jQuery一般会调用jQuery.param()将对象转化成字符串(除了下面提到的一个异常)。该工具函数会将对象的属性当成名/值对,例如,会将对象{x:1,y:"hello"}转化为字符串"x=1&y=hello"。
若是传递给jQuery.getJSON()的URL或数据字符串在末尾或“&”字符前含有"=?"字符串, 则代表这是一个JSONP请求。jQuery会建立一个回调函数,并用该回调函数的函数名替换掉"=?"中的“?”号,接着jQuery.getJSON()的行为就会想请求脚本文件同样,而不是JSON对象。这对金泰的JSON数据文件无效,它只能与支持JSONP的服务器脚本一块儿才能工做。因为JSONP被当作脚原本处理,这意味着JSON格式的数据能够跨域请求。
⑶.jQuery.get()和jQuery.post()
jQuery.get()和jQuery.post()获取指定URL的内容,若是有数据的话,还能够传入指定数据,最后则将结果传递给指定的回调函数。jQuery.get()使用HTTP GET请求来实现,jQuery.post()使用HTTP POST请求,其它二者则是同样的。与jQuery.getJSON()同样,这两个方法也是接受相同的三个参数:必需的URL,可选的字符串或对象,以及一个技术上可选但实际上总会使用的回调函数。调用的回调函数会传入三个参数:第一个参数是返回的数据;第二个是“success”;第三个则是XMLHttpRequest对象(若是有的话):
// 从服务器上请求文件并在警告对话框中显示 jQuery.get("ajax/debug.txt",alert);
除了上面描述的三个参数,还有两个方法接受可选的第4个参数(若是省略数据参数的话,则做为第三个参数传入),该参数指定被请求数据的类型。第4个参数会影响在传入回调函数前数据的处理。load()方法使用"HTML"类型,jQuery.getScript()使用“script”类型,jQuery.getJSON()则使用"json"类型。与上面这些专用的函数相比。jQuery.get()和jQuery.post()更灵活。该参数的有效值,以及省略该参数时jQuery的行为,下面描述。
jQuery的Ajax数据类型
能够给jQuery.get()或jQuery.post()传递下面6种类型做为参数。此外,下面会讲到,使用dataType选项也能够传递这些类型给jQuery.ajax()方法:
"text"
将服务器的响应做为纯文本返回,不作处理
"html"
类型和"text"同样:响应是纯文本。load()方法使用该类型,将返回的文本插入到文档目录自身中。
"xml"
请求的URL被认为指向XML格式的数据,jQuery使用XMLHttpRequest对象的responseXML属性来替代reponseText属性。传给回调函数的值是一个表示该XML文档的Doccument对象,而不是保存文档文本的字符串。
"script"
请求的URL被认为指向javascript文件,返回的文本在传入回调函数钱,会当作脚本执行。jQuery.getScript()使用该类型。当类型是“script”时,jQuery可使用script元素来替代XMLHttpRequest对象,所以用来处理跨域请求。
"json"
请求的url被认为指向json格式的数据文件。会使用jQuery.parseJSON()(参考7节)来解析返回的内容,获得JSON对象后传入回调函数。jQuery.getJSON()使用该类型。若是类型是"json"同时URL或数据字符串含有“=?”会被转换成jsonp。
"jsonp"
请求的url被认为指向服务器脚本,该脚本支持jsonp协议,能够将json格式的数据做为参数传递给客户端指定的函数。(jsonp的更多的细节请参考16.2节)在该类型下,传递给回调函数的是解析好的对象。因为jsonp请求能够经过script元素来实现,所以该类型能够用来跨域请求,就和使用script类型同样。使用该类型时,url或数据字符串常常会包含一个相似"&jsonp=?"或"&callback=?"的参数。jQuery会将其中的"?"替换为自动产生的回调函数名。(可参考6.3,(3)不经常使用的选项和钩子节中的jsonp和jsonpCallback选项来替代)
若是调用jQuery.get()、jQuery.post()或jQuery.ajax()函数时没有指定以上类型中的任何一个,jQuery会检查HTTP响应中的Content-Type头。若是该头部信息包含“XML”字符串,则传入回调函数中的是xml文档。不然,若是头部包含"json"字符串,则数据被解析成JSON并把解析后的对象传递给回调函数。不然,若是头部含有javascript字符串,则数据被当成脚本执行。若是以上都不符合,则数据会被当成纯文本执行。
3.jQuery.ajax()函数
jQuery的全部的Ajax工具都会调用jQuery.ajax()————这是这个库中最复杂的函数。jQuery.ajax()仅接受一个参数:一个选项对象,该对象的属性指定ajax请求如何执行的不少细节。例如:jQuery.getScript(url,callback)与如下jQuery.ajax()调用等价:
jQuery.ajax({ type:"get",//HTTP请求方法 url:url, //要获取数据的地址 data:null, //不要给url添加任何数据 dataType:"script", //一旦获取到数据,当即执行当前脚本 success:callback //完成时调用的函数 });
jQuery.get()和jQuery.post()也接受上面这5个基本选项。然而,若是直接调用jQuery.ajax()的话,它能够支持更多的选项。下面会解释全部选项(包含上面5个基本选项。)
在深刻了解全部选项以前,咱们得知道能够经过给jQuery.ajaxSetup()传入一个详细对象来设置任意默认值:
jQuery.ajaxSetup({ timeout:2000, //在2秒后取消全部ajax请求 cache:false //经过给url添加事件戳来禁用浏览器缓存 });
运行以上代码后,指定的timeout和cache选项会在全部未指定这两个选项的值的Ajax请求中使用,包括jQuery.get()和load()等高级工具。
在阅读下面章节中,jQuery的大量选项和回调函数时,参考6.i和6.ii节下面的"(3).jQuery.get()和jQuey.post()"节中关于jQuery Ajax状态码和数据类型字符串的内容很是有助于理解。
(1).通用选项
jQuery.ajax()中经常使用的选项以下:
type
指定http的请求方法。默认是"GET".另外一个经常使用值是"POST".能够指定其它HTTP方法,好比"DELETE"或"PUSH",但不是全部的浏览器都支持它们。
url
要获取的url.对于GET请求,data选项会添加到该URL后。对于JSONP请求,当cache选项为false时,jQuery能够添加参数到URL中。
data
添加到URL中(对于GET请求)或请求在主体内容中(对POST请求)发送的数据。这能够是字符串也能够是对象。一般会把对象转化为字符串,就如6.ii节下面的(2)jQuery.getJSON()节中描述的同样,除了在process data选项中描述的异常状况。
dataType
指定响应数据的预期类型,以及jQuery处理该数据的方式。合法的值是"text" "html" "script" "json" "jsonp" "xml"。6.ii下面的(3)jQuery.get()和jQuery.post()节有解释这些值的含义。选项没有默认值。当没有指定时,jQuery会检测响应中的Content-Type头来肯定如何处理返回的数据。
contentType
指定请求的HTTP Content-Type头。默认是"application/x-www-form-urlencoded",这是HTML表单和绝大部分服务器脚本使用的正常值。若是将type选项设置为"POST",想发送纯文本或XML文档做为请求体时,须要设该值。
timeout
超时时间,当请求没有在指定的时间内完成时,请求会取消同时触发error回调,回调中心的状态码参数为"timeout"。默认超时时间为0,表示除非请求完成,不然永远不取消。
cache
对于GET请求,若是该选项设置为fasle,jQuery会添加一个“_=”参数到URL中,或者替换已经存在的同名参数。该参数的值是当前时间(毫秒格式)。这能够禁用浏览器缓存,由于每次请求的URL都不同
ifModified(此处省略)
global
该选项指定jQuery是否应该触发上面描述的Ajax请求过程当中的事件。默认是true;设置改选项为false会禁用ajax相关全部事件。(参考6.iiii获取事件的细节)。
⑵回调
下面的选项指定在Ajax请求的不一样阶段调用的函数。success选项已经很熟悉了:则是传入给jQuery.getJSON()等方法的回调函数。注意jQuery也会将AJax请求过程的消息当作事件发送(除非设置了global选项为false)。
context
该选项指定回调函数在调用时的上下文对象————就是this。该选项没有默认值,若是不设置,this会指向选项对象。设置context选项也会影响Ajax事件触发的方式(参考6.iiii节)。若是设置该选项,值应该为window、Document或触发事件所在的Element。
beforeSend
该选项指定Ajax请求发送到服务器以前激活的回调函数。第一个参数是XMLHttpRequest对象,第二个参数是该请求的选项对象。beforeSend回调使得程序有机会在XMLHTTPRequest对象上设置自定义HTTP头部。若是改回调函数返回false,Ajax请求会取消。注意跨域的的script和jsonp请求没有使用XMLHttpRequest对象,所以不会触发beforeSend回调。
succes
该选项指定Ajax请求成功完成时调用的回调函数。第一个参数是服务器发送的数据;第二个参数是jQuery状态码;第三个是用来发送请求的XMLHTTPRequest对象。6.ii下面的(3)jQury.get()和jQuery.post()节所描述,第一个参数的类型取决于dataType选项服务器响应的Content-Type头信息。若是类型是“XML”,则第一个参数是Document对象。若是类型是json或jsonp,第一个参数是返回服务器的JSON格式响应的解析结果。若是类型是script,则响应内容是所加载脚本的文本内容(该脚本已经执行了,所以在这种状况下能够忽略响应内容。)对于其余类型,响应内容直接就是请求资源的文本内容。
第二个参数的状态码一般是字符串"succes",若是设置了ifModified选项,该参数就多是"notmodified"。这种状况下,服务器不发送响应而且不顶用第1个参数。“script”和"jsonp"类型的跨域经过请求<script>元素而不是XMLHttpRequest执行,对于那些请求,不会定义第三个参数。
error
该选项指定Ajax请求不成功时的回调函数。该回调的第1个参数是该请求的XMLHTTPRequest对象(若是可能用到的话)。第二个参数是JQuery的状态码。对于HTTP错误,该状态码多是“Error”,对于超时,则是"timeout",“parsererror”则表示解析服务器响应时出了问题。例如:xml文档或json对象不符合格式,则状态码为"parsererror"。这种状况下,error回调的第三个参数则是抛出的Error对象。注意dataType为“script”的请求在返回无效的javascript代码时不会触发错误。脚本的任何错误都会忽略掉,调用的回调则是success而不是error。
complete
该对象指定ajax请求完成时激活的回调函数。每个ajax请求或者成功调用success回调。当失败时调用error回调。在调用success或error后,jQuery会调用complete回调。传给complete回调的第一个参数是XMLHTTPRequest对象,第二个参数则是状态码。
⑶.不经常使用的选项和钩子
下面的ajax选项不常用。某些特定的选项一般不可能设置。令一些选项则提供了自定义的钩子,是的能够修改jQuery Ajax请求的默认处理方式
async
脚本化化的HTTP请求自己就是异步的。然而,XMLHTTPRequest对象提供了一个选项,能够阻塞当前进程,直到接手到响应。若是想开启这一阻塞行为,设置该选项为false。设置该选项不会更改jQuery.ajax()的返回值:若是有使用XMLHTTPRequest对象的话,该函数会始终返回该对象。对于同步请求,能够从XMLHTTPRequest对象中提取服务器的响应和HTTP状态码,若是想要获取jQuery解析的响应和状态码,能够指定一个complete回调(就和给异步请求指定的同样)。
dataFilter
该选项指定一个函数,用来过滤或预处理服务器返回的数据。第一个参数是从服务器返回的原始数据(字符串或XML请求返回的Document对象),第二个参数是dataType的详细的值。若是指定该函数,则它必须返回一个值,该值会来替换掉服务器的响应。注意dataFilter()函数会在JSON解析和脚本执行前执行。同时注意跨域的script和jsonp请求不会调用dataFilter().
jsonp
当设置dataTpye选项为"jsonp"时,url或data选项一般会包含一个相似"jsonp=?"参数。若是jQuery在URL或data选项中没有找到相似参数时,会使用该选项指定的名字插入一个。该选项的默认值是callback.在使用jsonp时,若是服务器须要一个不一样的参数吗,而url或data选项中又没有指定时,须要设置该选项。
jsonpCallback
对于dataType选项为“jsonp”的请求(或url中带有相似"jsonp=?"这种JSONP参数的“json”请求),jQuery必须将url中的"?"替换成包装函数,服务器会将数据传递给该该包装函数。一般,jQuery会根据当前时间来生成一个惟一的函数名。若是想用本身的函数来替代jQuery生成的,则能够设置该选项。可是,一旦这样作了,会阻止jQuery在触发正常时间时调用success或complete回调。
processData
当设置data选项为对象(或将对象做为第二个参数传递给jQuery.get()和相关方法)时,jQuery一般将对象转换为字符串,该字符串遵循标准的HTML“application/x-www-form-urlencoded”格式(参考6.ii(2)jQuery.getJSON()节)。若是想省略掉该步奏(好比想将Document对象做为POST请求总体发送,)请设置该选项为false。
scriptCharset
对于跨域的"script"和"jsonp"请求,会使用<script>元素,选项用来指定它的元素的charset属性值。该选项对正常的基于XMLHttpRequest请求不会有任何做用。
tranditional
jQuery1.4改变了数据对象序列化为"application/x-www-form-urlencoded"字符串的方式(细节参考6.ii(2)jQuery.getJSON()节)。设置该选项为true,可让jQuery回复到原来的方式。
usename,password
若是请求须要密码验证,请使用着两个选项来指定用户名和密码
xhr
该选项指定一个工厂函数,用来获取XMLHTTPRequest对象。该工厂函数在调用时不带参数,并且必须返回一个实现了XMLHTTPRequest API对象。这个很是底层的钩子能够建立本身对XMLHTTPRequest的包装,能够给方法添加特性或测量。
iiii.Ajax事件
6.iii节中的“回调”节描述了jQuery.ajax()拥有的4个回调选项:beforeSend、success、error、complete。除了分别激活这些制度的回调函数,jQuery的Ajax函数还会在Ajax请求的每个相同阶段触发自定义事件。下面的表格展现了这些回调函数响应的事件:
回调 | 事件类型 | 处理程序注册方法 |
beforeSend | "ajaxSend" | ajaxSend() |
sucess | "ajaxSuccess" | ajaxSucess() |
error | "ajaxError" | ajaxError() |
complete | "ajaxComplete" | ajaxComplete() |
"ajaxStart" | ajaxStart() | |
"ajaxStop" | ajaxStop() |
可使用bind()方法和上表第二列中的事件类型字符串来注册这些自定义Ajax事件,也可使用第三列中的事件注册方法来注册。ajaxSuccess()和其它方法的使用方式就用click()、mouseover()以及4.i节中中的其它简单事件注册方法同样。
因为Ajax事件是自定义事件,是由jQuery而不是浏览器产生的,所以传递给事件处理程序的Event对象不是颇有用。其实,ajaxSend、ajaxSuccess、ajaxError和ajaxComplete事件在触发时都带有其它参数。这些事件的处理程序激活时再event参数后都带有两个额外的参数。第一个额外的参数是XMLHTTPRequest对象,第二个额外参数是选项对象。例如,这意味着ajaxSend事件的处理程序能够向XMLHttpRequest对象添加自定义头,就和beforeSend回调能够作的同样。除了上面描述的两个额外参数,触发ajaxError事件时还会带有第三个额外参数。若是有的话,事件处理程序的第三个额外参数是Error对象,是在发生错误时抛出的。使人奇怪的是,这些Ajax事件并无传入jQuery的状态码。例如,若是ajaxSuccess事件的一个处理程序须要区分“success”和"notmodified",则它须要从XMLHTTPRequest对象中检测元素HTTP状态码。
上面表格中例举的最后两个事件与其余事件不一样,最明显的是他们没有响应的回调函数,同时他们在触发时不带额外参数。ajaxStart和ajaxStop是一对表示与Ajax相关的网络活动开始和中止的事件。当jQuery没有执行任何Ajax请求时,若是开始一个新请求,它就会触发ajaxStart事件。若是在第一个请求尚未完成是,其它请求就开始了。这些新请求不会触发新的ajaxStart事件。这一对事件能很方便地用来显示和隐藏某些“加载中。。。”动画或网络的图标:
$("#loading_animate").bind({ ajaxStart:function () { $(this).show(); }, ajaxStop: function () { $(this).hide(); } });
这些ajaxStart和ajaxStop的事件处理程序能够绑定到任意文档元素上:jQuery是全局的触发它们(4.iiiiii)。其它4个ajax事件,ajaxSend、ajaxSuccess、ajaxError、ajaxComplete、一般也是全局触发的,所以,处理程序能够绑定到任何元素上。而后,若是在调用jQuery.ajax()时设置了context选项,则这4个事件不会全局触发,而会在context元素上触发。
最后,记住能够经过设置global选项为false来组织jQuery触发任何Ajax相关的事件。尽管这个选项名很让人迷惑,可是设置global为false可让jQuery再也不在context对象上触发事件已经再也不全局地触发事件。
7.工具函数
jQuery类库定义了很多工具函数(还有两个属性),在编写程序时挺有用。在下面的列表中你会发现,部分函数在ECMAScript中已经有了等价的形式。jQuery的函数比ES5早,而且能够工做在全部浏览器中。按照字母排序,将这些工具函数列举以下:
jQuery.browser
if($.browser.mozilla && parseInt($.browser.version) < 4) { //...在此解决假设的firefox bug }
jQuery.contains()
该函数接受两个文档元素做为参数。若是第一个元素包含第二个元素,则返回ture;不然返回false。
jQuery.each()
和each()方法不一样,each()方法只能变量jQuery对象,而jQuery.each()工具函数能够遍历数组元素或对象上调用的函数。第二个参数是要在每一个数组元素或对象属性上调用的函数。该函数在调用时会带有两个参数:数组元素的序号或对象的属性名,以及数组元素的值或对象的属性值。函数中的this值和第二个参数是同样的。若是该函数返回false,jQuery.each()会中止当前遍历会当即返回。jQuery.each()总会返回第一个参数的值。
jQuery.each()会使用普通的for/in循环来遍历对象属性,全部会遍历全部可枚举的属性,包含继承的属性。jQuery.each()在遍历数组元素时,会以序号从小到大来遍历,不会跳过稀疏数组中的undefined属性。
jQuery.extend()
该函数接受对象做为参数。它会将第二个以及之后参数对象的属性复制到第一个参数对象中,若是同名的属性已经在第一个参数对象中,则会覆盖它。该函数会忽略任何值为undefined或null的属性。若是仅传入了一个对象,该对象的属性会被复制到jQuery对象自身中。该对象的返回值是属性被复制到的对象。若是一个参数的值为true,则会执行拷贝:第三个(以及之后)对象的属性会被复制到第二个对象上。
该函数用来复制对象以及合并带有几组默认值的选项对象时很是有用:
var clone = jQuery.extend({},original); var options = jQuery.extend({},default_options,user_options);
jQuery.globalEval()
该函数会在全局上下文中执行javascript代码字符串,就像它是<script>的元素内容同样。(实际上,jQuery实现该函数时,就是经过建立一个<script>元素并临时把它插入到文档中来显示的。(新版的jQuery里,已经优化了实现,实现了eval和execScript来执行))。
jQuery.gerp()
该函数和ES5中的Array对象的filter()方法相似。它接受数组做为第一个参数,以及一个判断函数做为第二个参数,该判断函数会在数组的第一个元素上调用,调用时会传入元素值和元素的序号做为参数。jQuery.gerp()返回一个新数组,该数组由调用判断函数时返回true(或其余真值)的元素组成。若是给jQuery.gere()传入true做为第三个参数,则它会反转判断函数,返回的数组将会判断函数调用时为false或其余假值的元素组成。
jQuery.inArray()
该函数和ES5中的Array对象indexOf()方法相似,它的第一个参数能够是任意值,第二个参数则是数组(或类数组对象),返回值是第一个参数值在数组中第一次出现的序列号,若是该参数只不存在的话,则返回-1.
jQuery.isArray()
当参数是原生对象时,返回true.
jQuery.isEmptyObject()
当参数对象没有可枚举的属性是,返回true.
jQuery.isFunction()
当参数是元素Function对象时,返回true。注意,在IE8及之前的版本中,window.alert()和window.attachEvent()等浏览器方法返回false。
jQuery.isPlainObject()
若是参数是“纯”对象,而不是某些特定类型或类对象的实例时,返回true
jQuery.makeArray()
若是参数是类数组对象,该函数会将对象的属性复制到一个新的(真)数组中,并返回该数组。若是参数不是类数组对象,该函数会仅返回一个新数组,该数组只包含传入的参数一个元素。
jQuery.map()/jQuery.merge()/jQuery.parseJSON()/jQuery.proxy()/jQuery.support()/jQuery,trim()
8.jQuery选择器和选取方法
在本章中,咱们已经使用了简单CSS选择器的jQuery选取函数:$()。如今是时候深刻的了解jQuery选择器语法,以及一些提早和扩充选中元素集的方法了。
i.jQuery选择器
在CSS3选择器标准草案定义的选择器语法中,jQuery支持至关完整的一套子集,同时还添加了一些非标准但颇有用的伪类。13.2.iiiii咱们描述过基本的css选择器。在此增长更多的高级选择器的阐述。注意:本节讲述的是jQuery选择器。其中有很多选择器(但不是所有)能够在CSS样式表中使用。
选择器语法有三层结构。最简单形式:"#test"选取id为"test"的元素。"blockquote"选取文档中的全部<blockquote>元素,而"div.note"则选取全部class属性为"note"的<div>元素。简单选择器能够组合成"组合选择器",好比"div.note>p"和"blockquote i",只要用组合字符分隔符就行。简单选择器和组合选择器还能够拆分红逗号分隔的列表。这种选择器组是传递给$()函数最多见的形式。在解释组和选择组以前,咱们必须莉皎简单选择器语法。
⑴.简单选择器
简单选择器的开头部分(显式或隐身地)是标签类型声明。例如,若是只对<p>元素感兴趣,简单选择器能够用"p"开头。若是选取的元素和标签名无关,则可使用通配符"*"号来代替。若是选择器没有蚁标签名或通配符开头,则隐式还有一个通配符。
标签名或通配符指定了备选文档元素的一个初始集。在简单选择器中,标签类型声明以后的部分由多个过滤器组成。过滤器从左到右应用,和书写顺序一致,其中每个都会缩小选中的元素集。
(jQuery选择过滤器请参考:http://file.ahthw.com/jq110/ ,这次略去介绍)
⑵.组合选择器
使用特殊操做符或“组合符”能够将简单选取组合起来,表达文档树中元素的关系。表达文档树中元素之间的关系。下面例举了jQuery支持的组合选择器。这些组合选取与Css3支持的组合选择器是同样的。
jQuery的组合选择器 | |
组合方式 | 含义 |
A B | 从匹配选择器A的元素的子孙元素中,选取匹配选择器B的文档元素。注意在这种中和方式下,组合符就是空白字符 |
A > B | 从匹配选择器A元素的子元素中,选取匹配选择器B的文档元素 |
A + B | 从匹配选择器A的下一个兄弟元素(忽略文本节点和注释)中,选取匹配选择器B的文档元素 |
A ~ B | 从匹配选择器A的元素后面的兄弟元素中,选取匹配选择器B的文档元素 |
下面是组合选择器的一些例子:
"blockquote i" //匹配<blockquote>里的<i>元素 "ol > li" //<li>是<ol>的直接子元素 "#output + *" // id="output"元素后面的兄弟元素 "div.note > h1 + p" //紧跟<h1>的<p>元素,在class = "note"里边
注意组合选择器并不限于组合两个选择器:组合三个甚至更多选择器也是容许的。组合选择器从左往右处理。
⑶.选择器组
传递给$()函数(或在样式表中使用)的选择器就是组合选择器,这是一个逗号分隔的列表,由一个或多个简单选择器或组合选择器构成。选择器组合匹配的元素只要匹配该选择器中的任意一个选取就行。对咱们来讲,一个简单选择器也能够认为是一个选择器组。下面是选择器组的一些例子:
"h1,h2,h3" //匹配<h1> <h2> <h3>元素 "#p1, #p2, #p3" //匹配id为p一、p2或p3的元素 "div.note, p.note" //匹配class为note的 div和p元素 "body>p,div.note>p" // <body>和class为note的P元素
注意:CSS和jQuery选择器语法容许在简单选择器的某些过滤器中使用圆括号,但不容许使用圆括号来进行更常见的分组。例如,不能把选择器组或组合选择器放在圆括号中而且当成简单选择器:
(h1, h2, h3)+p //非法 h1+p, h2+p , h3+p //正确的写法
ii.选取方法
除了$()函数支持的选择器语法,jQuery还定义了一些选取方法。本章咱们已经看到过大部分jQuery都是在选中元素上执行某种操做。选取方法不同:他们会修改选中元素集,对其进行提取、扩充或仅做为选取操做的起点。
本节描述的这些选取方法。请注意这些选取方法中的多数提供的功能于选取语法的功能是同样的。
提取选中元素最简单的方式是按位置提取。first()返回jQuery对象仅包含选中元素中的第一个,last()返回jQuery对象则只包含一个元素。更通用的是,eq()方法返回的jQuery对象只包含指定序号的单个选中元素。(在jQuery 1.4中,负序号也是容许的,会从选取的末尾开始计数。)注意这些方法返回的jQuery对象只有一个元素。这与常见的数组序号是不同的,数组序号返回的单一元素没有通过jQuery包装:
var paras = $("p"); paras.first() //选取第一个<p>元素 paras.last() //选取最后一个<p> paras.eq(1) //选取第二个<p> paras.eq(-2) //选取倒数第二个<p> paras[1] //第二个<p>元素自身
经过位置提取选取更通用的方法是slice()。jQuery的slice()方法与Array.slice()方法相似:前者接受开始和结束序号(负号会从结尾处计算),返回的jQuery对象包含从开始到结束序号(但不包含结束序号)处的元素集。若是省略结束序号,返回的对象会包含从开始序号起的全部元素。
$("p").slice(2,5) //选取第3 4 和第5个P元素 $("div").slice(-3) // 选取最后3个<div>元素
filter()是通用的选取过滤方法,有3种调用方式:
$("div").filter(".note") //与$("div.note")同样 $("div").filter($(".note")) //与$("div.note") 同样 $("div").filter(function(idx){ return idx%2==0 }) //与$("div:even") 同样
not()方法与fliter()同样,除了含义与fliter()相反。若是传递选择器字符串给not(),它会返回一个新的jQuery对象,该对象只包含不匹配该选择器的元素。若是传递给jQuery对象、元素数组或单一元素给not(),它会返回包含不匹配该选择器的元素。若是传递jQuery对象、元素数组或单一元素给not(),它会返回除了显式排除的元素以外的全部选中元素。若是传递判断函数给not(),该判断函数的调用就与在filter()中同样,只是返回的jQuery对象仅包含哪些使得判断函数返回false或其余假值的元素:
$("div").not("#header,#footer"); //除了两个元素以外的全部<div>元素
在jQuery 1.4中,提取选取的另外一种方式是has()方法。若是传入选择器,has()会返回一个新的jQuery对象,仅包含有子孙元素匹配该选择器的选中元素。若是传入文档元素给has(),它会将选中元素即调整为那些是指定元素祖先节点的选中元素:
$("p").has("a[href]") //包含连接的段落
add()方法会扩充选取,而不是对其进行过滤或提取。能够将传给$()函数的任何参数(除了函数)照样传给add()方法。add()方法会返回原来的选中元素,加上传给$()函数的那些参数所选中(或建立)的那些元素。add()会移除重复元素,并对该组合选取进行排序,以便利民的元素按照文档中的顺序排列:
//选取全部<div>和全部<p>元素的等价方式 $("div,p") //使用选择器组 $("div").add(p) //给add()传入选择器 $("div").add($("p")) //给add()传入jQuery对象 var paras = document.getElementsByTagName("p"); //类数组对象 $("div").add(paras); //给add()传入元素数组
⑴.将选中元素即用作上下文
上面描述的filter()、add()、和not()方法会在各自的选中元素集上执行交集、并集和差集运算。jQuery还定义一些其余选取方法可将当前选中元素集做为上下文来使用。对选中的每个元素,这些方法会使用该选中元素做为上下文或起点来获得新的选中元素集,而后返回一个新的jQuery对象,包含全部新的选中元素的并集。与add()方法相似,会移除重复元素并进行排序,以便元素按照在文档中出现的顺序排列好。
该类别选取方法中最通用的是find()。它会在每个当前选中元素的子孙元素中寻找与指定选择器字符串匹配的元素,而后它返回一个新的jQuery对象来表明所匹配的子孙元素集。注意这些新选中的元素不会并入已经村长的选中元素集中。同时注意find()和filter()不一样,filter()不会选中新元素,只是简单地将当前选择的元素进行缩减:
$("div").find("p") //在<div>中查找<p>元素,与$("div p")相同
该类别中的其余方法返回新的jQuery对象,表明当前选中元素集中每个元素的子元素、兄弟元素或父元素。大部分都接受可选的选择器字符串做为参数。不传入选择器时,它会返回全部子元素、兄弟元素或父元素。传入选择器时,他们会过滤元素集。传入选择器时,他们会过滤元素集,仅限返回匹配的。
children()方法返回诶一个选中元素的直接子元素,能够用可选的选择器参数进行过滤:
//寻找id为"header"和"footer"元素自及诶按元素中的<span>元素 // 与$("#header>span, #footer>span")相同 $("#header,#footer").children("span")
contents()方法与children()方法相似,不一样的是它会返回每个元素的全部子节点,包括文本节点。若是选中元素集中有<iframe>元素,contents()还会返回该<iframe>内容的文档内容。注意contens()不接受可选的选择器字符参数————由于它返回的文档节点不彻底是元素,而是选择器字符串仅用来描述元素的节点。
next()和prev()方法返回每个选中元素上一个和上一个兄弟元素(若是有的话),若是传入了选择器,就只会匹配该选择器的兄弟元素:
$("h1").next("P") //与$("h1+p")相同 $("h1").prev() //<h1>元素前面的兄弟元素
nextAll()和prevAll()返回每个选中元素前面或后面的全部兄弟元素(若是有的话)。siblings()方法则返回每个选中元素的全部兄弟元素(选中元素自己不是本身的兄弟元素)。若是这些方法传入选择器,则只会返回匹配的兄弟元素:
$("#footer").nextAll("p") //紧跟#footer元素的全部<p>兄弟元素 $("#footer").prevAll() //#footer元素前面的全部兄弟元素
jQuery1.4开始,nextUntil()和prevUntil()方法接受一个选择器参数,会选取选择元素后面或前面的全部兄弟元素,知道找到某个匹配该选择器的兄弟元素为止。若是省略该选择器,这两个方法的做用域就和不带选择器的nextAll()和prevAll()同样。
parent()方法返回每个选中元素的父节点:
$("li").parent() //列表元素的父节点,好比<ul>和<ol>元素
parents()方法返回每个选中元素的祖先节点(向上直到<html>元素)。parent()和parents()都接受一个可选的选择器字符串参数:
$("a[href]").parents("p") //含有连接的p元素
parentsUntil()返回每个选中元素的祖先元素,直到出现匹配指定选择器的第一个祖先元素。closest()方法必须传入一个选择器的字符串,会返回每个选中元素的祖先元素中匹配该选择器的最近一个祖先元素(若是有的话)。对于方法而言,元素被认为是自身的祖先元素,在jQuery1.4中,还能够给closet()传入一个祖先元素做为第二个参数,用来阻止jQuery往上查找时超越该指定元素:
$("a[href]").closest("div") //包含连接是最里层的<div> $("a[herf]").parentUntil(":not(div)") //全部包裹<a>的<div>元素
⑵.恢复到以前的选中元素集
为了实现方法链式调用,不少jQuery对象的方法最后都返回调用对象。然而本节讲述的方法都返回新的jQuery对象。能够链式调用下去,但必须清晰的意识到,在链式调用的后面所操做的元素集,可能已经不是该链式调用开始时的元素集了。
实际状况还要复杂些。当这里所描述的选取方法在建立或返回一个新的jQuery对象时,它们会给该对象添加一个到它派生自旧的jQuery对象的内部引用。这会建立一个jQuery对象的内部引用。这会建立一个jQuery对象的链式表或栈。end()方法用来弹出栈,返回保存的jQuery对象。在链式调用中调用end()会将匹配元素还原到以前的状态。考虑以下代码:
//寻找全部的<div>元素,而后在其中寻找<p>元素 //高亮显示<p>元素,而后给<div>元素添加一个边框 //首先,不使用链式调用 var divs = $("div"); var paras = div.find("p"); paras.addClass("heiglight"); divs.css("border","solid black 1px"); //下面展示如何使用链式调用来实现 $("div").find("p").addClass("heiglight").end().css("border","solid black 1px"); //还能够将操做调换顺序来避免调用end() $("div").css("border","solid block 1px").find("p").addClass("heiglight");
若是想手动定义选中元素集,同时保持与end()方法的兼容,能够将新的元素集做为数组或类数组对象传递给pushStack()方法。指定的元素会成为新的选中元素,以前选中的元素集则会压入栈中,以后能够用end()方法还原他们:
var sel = $("div"); //选取全部div元素 sel.pushStack(document.getElementsByTagName("p")); //修改成全部p元素 sel.end(); //还原为div元素
既然咱们已经讲解了end()方法及其余使用的选区栈,就有最后一个方法须要讲解。andSelf()返回一个新的jQuery对象,包含当前所选中元素,加上以前的全部选中元素(会去除重复的)。andSelf()和add()方法同样,或许"addPrev"是一个更具描述性的名字。做为例子,考虑上面代码的下述变化,或许“addPrev”是一个更具备描述性的名字。做为例子,考虑上面代码的下述变化:高亮显示<p>元素及其父节点的<div>元素,而后给这些div加上边框:
$("div").find("p").andSelf(). addClass("highligeht"). end().end().css("border","solod black 1px");
9.jQuery的插件扩展
jQuery的写法是的添加新功能非常方便。添加新功能的模块称为插件(plug-in),能够在这里找到不少插件:http://plugins.jquery.com。jQuery插件是普通的javascript代码文件,在网页中使用时,只须要用 javascript的src方式引入就好,就和引用其它javascript类库同样,注意:必须在jQuery以后引入jquery插件
开发jQuery插件很是简单。关键点是要知道jQuery.fn是全部jQuery对象的原型对象。若是给该对象添加一个函数,该函数就会成为一个jQuery方法,例子以下:
jQuery.fn.println = function() { //将全部参数合并成空格分隔的字符串 var msg = Array.prototype.join.call(arguments," "); //遍历jQuery对象中的每个元素 this.each(function(){ //将参数字符串作为春文本添加到每个元素后面,并添加一个<br/> jquery(this).append(document.createTextNode(msg).append("<br/>")); }); //返回这个未添加的jQuery对象,以便链式调用 return this; }
经过上面对jQuery.fn.parintln()函数的定义,咱们能够在任何jQuery对象上相似以下调用println()方法了:
$("#debug").println("x = ", x, "; y = ", y);
这是添加新方法到jQuery.fn中常见的开发方式。若是发现本身在使用each()方法“手动”遍历jQuery对象中的元素,并在元素上执行某些操做时,就能够问问本身,是否能够将代码重构下,使得这些each()回调移动到一个扩展方法里(jQuery插件的这种扩展方式是全局性的,带来方便的同时,也污染了jQuery对象,容易形成潜在冲突,译者并不推荐“随时着想”使用这种扩展方式)。在开发扩展功能时,若是遵照基本的模块化代码实践,以及遵照jQuery特定的一些传统约定,就能够将该扩展成为插件,与他人分享。下面是一些值得留意的jQuery插件约定:
(function($){ //带有参数名为$的参数 // 在这里书写插件的代码 }(jQuery));
//插件能够给jQuery自身增长函数来添加新的工具函数。例如: //插件输出其参数(使用println()方法) //到id为"debug"的元素上。若是不存在该元素,则建立一个并添加到新的文档中 jQuery.debug = function(){ var elt = jQuery("#debug");//查找#debug元素 if(elt.length == 0){ //若是它不存在,则建立之 elt = jQuery("<div id='debug'><h1>debugging output</h1></div>"); jQuery(document.body).appedn(elt); } elt.prinltln.apply(elt,arguments); //将参数输出到元素中 };
除了定义新方法,还能够扩展jQuery类库的其余部分。例如,在5节中,咱们已经看到能够经过jQuery.fx.speeds添加属性来扩充新的红花时长名了(除了"fast"和"slow"),也能够经过给jQuery.easing添加属性来添加新的缓动函数。插件甚至能够扩展jQuery的css选择器引擎!能够经过给jQuery.expr[':']对象添加新的伪类过滤器(好比:first和:input)。下面的例子定义了一个新的draggable过滤器,能够用来返回拥有draggable=true属性的元素:
jQuery.expr[':'].draggable = function(e){ return e.draggable === true; };
使用上面定义的选择器,能够用$("img[draggable=true]")来选取可拖拽的图片,而不用使用冗长的$("img[draggable=true]")。
从上面的代码中能够看出,自定义选择器函数的第一个参数是候选的DOM元素。若是改元素匹配选择器,则返回true;不然返回false。许多定义选择器只需这一个元素参数,但实际上在调用时他们传入了4个参数。第二个参数是整数序号,表示当前元素在候选数组中的位置。候选元素数组做为第4个参数传入,选择器不该该修改它。第三个参数是颇有趣的:这是调用RegExp.exec()方法返回的数组,若是有的话,该数组的第4个元素(序号是3)是伪类过滤后面的圆括号的中的值。圆括号和里面的人和引号都是去除了,只留下参数字符串。下面是一个例子,用来讲明如何实现一个:data(x)伪类,该伪类只在元素拥有data-x属性时返回true.
jQuery.expr(':').data = function (element,index,match,array){ //ie7如下不支持hasAttriBute() return element.hasAttribute("data-" +match[3]); };
10.jQuery UI类库
jQuery限定本身只提供核心的DOM、CSS、事件处理以及Ajax功能。这提供了一个很棒的基础,能够用来构建更高的抽象,好比用户界面组件,jQuery UI类库就是这么作的。
类如其名,jQuery UI定义了一些用户界面组件:输入区域的自动完成,输入日期的日期选择器,用来租住信息的手风琴页和标签页、可视化数字的滑块和进度条,以及用来和用户紧急通讯的模态对话框。除了这些组件,jQuery UI还实现了更通常化的“交互”,使得元素轻松就能够实现拖拽,放置,改变大小,可选取,可排序。最后,jQuery UI还给自身的效果方法提供了一些新的视觉效果方法,(还使得能够变化颜色)。同时能够定义不少新的缓动函数。
JQuery UI是彻底皮肤化的,它的皮肤能够采用CSS文件形式,所以除了要加载的jQuery UI的js文件到网页中,还须要引入皮肤的CSS文件。jQuery UI预约好了几套皮肤供下载。
jQuery UI组件和交互功能采用jQuery插件方法构建,每个都定义一个jQuery方法。一般,已存在的文件元素中调用方法是,会将元素转化为组件。例如:要改变输入文本,一遍在单击或聚焦文本输入框时要它弹出一个日期选取组件,直接用下面的代码调用datapicker()就行:
//将class="date"的input元素转化为日期选取组件 $("input.date").datepicker();
灵活的使用jQuery UI组件,须要熟悉三样东西:它的配置选项、它的方法以及它的事件。全部jQuery UI组件都是可配置的,有一些组件有不少配置选项。能够给组件方法传递选项对象(和在动画操做里,传递选项对象给animate()相似)来定义组件的外观和行为。
jQuery UI组件一般会定义至少有几个“方法”来与组件交互,可是,为了不jQuery方法的迅速增多,jQuery UI组件不会将它们的“方法”定义称为真正的方法。每一个组件只会有一个方法(与上面的datapicker()方法同样)。当须要调用组件的一个“方法”,时,须要给组件定义真正的方法传递预期“方法”名称,例如:想要禁止日期选取组件,不能调用disableDatapicker()方法。而须要调用datepicker("disable")。
jQuery UI组件一般会定义自定义事件,想要用户交互时触发它们。能够用经常使用的bind()方法来给这些自定义事件绑定事件处理程序,一般还能够将事件处理程序函数做为选项对象的属性,该选项对象会传递给组件方法。事件处理程序的第一个参数依旧是Event对象。某些组件还会传递一个“UI”对象做为事件处理程序的第二个参数。该对象一般提供了当前组件的状态信息。
注意:jQuery UI文档中有时描述的“事件”并非真正的自定义事件,可能描述为回调函数更好。这些回调函数是经过配置选项对象设置的。例如,日期选取组件支持很多回调函数,能够在不一样的时间点调用它。可是,这些函数中没有一个拥有标准的事件处理程序签名,不能使用bind()为这些“事件”注册处理程序。
正确的作法是:在初始调用组件方法时,给组件配置选项时,就指定合适的回调函数。
(本章完结)
上一章:第十六章:脚本化HTTP 下一章:第十八章:客户端存储