第十七章:jQuery類庫

javascript的核心API設計的很簡單,但因爲瀏覽器之間的不兼容性,致使客戶端的API過於複雜。IE9的到來緩解了這種狀況。然而使用javascript的框架或者工具類庫,能簡化通用操做,處理瀏覽器之間的差別,這讓不少程序員在開發web應用時變得更簡單。javascript

jQuery類庫被普遍的使用,做爲web開發者,咱們必須熟悉它:即使沒有在本身的代碼中遇到,也可能在別人的代碼中碰見。幸運的是,jQuery代碼足夠小巧和穩定,本章就能將它講述清楚。
jQuery能讓你在文檔中輕鬆找到關心的元素,並對這些元素進行操做添加內容編輯HTML屬性和css屬性定義事件處理程序以及執行動畫它還擁有Ajax工具來動態發起HTTP請求,以及一些通用的工具函數來操做對象和數組css

正如其名,jQuery類庫聚焦於查詢。一個典型的查詢使用CSS選擇器來識別一組文檔元素,並返回一個對象來表示這些元素。返回的對象提供了大量的方法來批量操做匹配的元素。這些方法會盡量返回調用對象自己,這使得簡潔的鏈式調用成爲可能。jQuery如此強大和好用,關鍵得益於如下特性:html

  • 豐富強大的語法(CSS選擇器),用來查詢文檔
  • 高效的查詢方法,用來找到與CSS選擇器匹配的文檔元素集
  • 一套有用的方法,用來操做選中的元素
  • 強大的函數式編程技巧,用來批量材質元素集,而不是每次只操做單個
  • 簡潔的語言語法(鏈式調用),用來表示一系列順序操做

本章首先會介紹如何使用jQuery來實現 簡單的查詢並操做其結果。接下來的章節會講解:java

  • 如何設置HTML屬性,CSS樣式和類、HTML表單的值和元素內容、位置高寬,以及數據
  • 如何改變文檔結構:對元素進行插入、替換、包裝和刪除操做
  • 如何使用jQuery的跨瀏覽器事件模型
  • 如何用jQuery來實現動畫視覺效果
  • jQuery的Ajax工具,如何使用腳原本發起HTTP請求
  • jQuery的工具函數
  • jQuery選擇器的全部語法,以及如何使用jQuery的高級選擇方法
  • 如何使用和編寫插件來對jQuery進行擴展
  • jQuery UI類庫

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()依舊是很好的選擇:

  • querySelectorAll()在新近的瀏覽器中才實現能,$()在新老瀏覽器中都能跟蹤
  • jQuery能夠經過手動實現選擇,所以$()支持的css3選擇器在全部的瀏覽器中,而不是支持css3的瀏覽器
  • $()返回類 數組對象(Jquery對象),吧querySlectctorAll()返回的類數組對象(NodeList)更加有用

想要遍歷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方法有個概要理解。

  • jQuery使用同一個方法即當getter又作setter用,而不是定義一對方法。若是傳入一個新值給該方法,則它設置此值;若是沒有指定值,則它返回當前值。
  • 用作setter時,這些方法會給jQuery對象中的每個元素設置值,而後返回該jQuery對象以方便鏈式調用。
  • 用作getter時,這些方法只會查詢元素集中的第一個元素,返回單個值。(若是要遍歷全部元素,請使用map()。)getter不會返回調用自身的jQuery對象,所以它只能出如今鏈式調用的末尾。
  • 用作setter時,這些方法常常接受對象參數。在這種情形下,該對象的每個屬性都指定一個須要設置的名/值 對。
  • 用作setter時,這些方法常常接受函數參數。在這種狀況下,會調用該函數來計算須要設置的值。調用該函數時的this值是對應的元素,第一個參數是該元素的索引值, 當前值則做爲第二個參數傳入

在閱讀本節接下來的內容時,請將對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種調用方式:

  1. 傳遞選擇器字符串給filiter(),它會返回一個jQuery對象,僅包含也匹配該選取中的選中元素。
  2. 傳遞另外一個jQuery對象給filter(),它會返回一個新的jQuery對象,該對象包含這兩個jQuery對象的交集。也能夠傳遞元素數組甚至單一文檔元素給filter()
  3. 傳遞判斷函數給filter(),會爲每個匹配元素調用該函數,filter()則返回一個jQuery對象,僅包含判斷函數爲true(或任意真值)的元素。在調用判斷函數時,this值爲當前元素,參數是元素序號。(參考jQuery.grep())
    $("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插件約定:

  •  不要依賴$標識符,包含的頁面可能調用了jQuery.noConfilict()函數,$()可能再也不等同於jQuery()函數。在上面簡短的插件裏只須要使用jQuery代替$就行。若是開發的擴展很長,則最好用一個匿名函數將擴展包裝起來,以免建立全局變量。若是這樣作,能夠將jQuery做爲參數傳遞給匿名函數,參數採用$:
  •     (function($){ //帶有參數名爲$的參數
         // 在這裏書寫插件的代碼
        }(jQuery));
  •  若是插件代碼不返回子的值,請確保返回jQuery對象以便鏈式調用。一般這就是this對象,不要不加修改地返回便可。在上面的例子中,方法末尾是"return this;"代碼行。遵照jQuery的另外一個習俗,可讓上面的方法更簡短寫(可讀性低一些):返回each()方法的結果。這樣,printlin()方法會包含"return this.each(function(){ ...... });"。 
  •  若是擴展方式擁有兩個以上參數或配置選項,請容許用戶能使用對象的方式傳遞選項(就像咱們在5.ii節看到的annimate()和6.iii看到的jQuery.ajax()函數同樣)
  •  若是插件須要使用data()方法與元素關聯數據,請將全部的數據值放在單一對象中,而後與插件名做爲命名空間名。(參見4.iiii節)。使用插件名做爲命名空間名
  •  若是須要插件使用data()方法與元素關聯數據,請將全部數據值放在單一對象中,而後用與插件名相同的鍵值名將該對象做爲單一值存儲。
  •  使用jquery,plugin.js這種文件命名方式將插件代碼保存到同一個文件中。
        //插件能夠給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 下一章:第十八章:客戶端存儲

相關文章
相關標籤/搜索