jQuery 概述

2021-09-15 16:20 更新

jQuery是目前使用最廣泛的JavaScript函數(shù)庫(kù)。據(jù)統(tǒng)計(jì),全世界57.5%的網(wǎng)站使用jQuery,在使用JavaScript函數(shù)庫(kù)的網(wǎng)站中,93.0%使用jQuery。它已經(jīng)成了開發(fā)者必須學(xué)會(huì)的技能。

jQuery的最大優(yōu)勢(shì)有兩個(gè)。首先,它基本是一個(gè)DOM操作工具,可以使操作DOM對(duì)象變得異常容易。其次,它統(tǒng)一了不同瀏覽器的API接口,使得代碼在所有現(xiàn)代瀏覽器均能運(yùn)行,開發(fā)者不用擔(dān)心瀏覽器之間的差異。

jQuery的加載

一般采用下面的寫法,在網(wǎng)頁(yè)中加載jQuery。

<script type="text/javascript" src="https://atts.w3cschool.cn/attachments/image/cimg/script>
<script>
window.jQuery || document.write('<script src="https://atts.w3cschool.cn/attachments/image/cimg/jquery-1.11.0.min.js" type="text/javascript"><\/script>')
</script>

上面代碼有兩點(diǎn)需要注意。一是采用CDN加載。如果CDN加載失敗,則退回到本地加載。二是采用協(xié)議無(wú)關(guān)的加載網(wǎng)址(使用雙斜線表示),同時(shí)支持http協(xié)議和https協(xié)議。

目前常用的jQuery CDN有以下這些。

上面這段代碼最好放到網(wǎng)頁(yè)尾部。如果需要支持IE 6/7/8,就使用jQuery 1.x版,否則使用最新版。

jQuery基礎(chǔ)

jQuery對(duì)象

jQuery最重要的概念,就是jQuery對(duì)象。它是一個(gè)全局對(duì)象,可以簡(jiǎn)寫為美元符號(hào)$。也就是說(shuō),jQuery和$兩者是等價(jià)的。

在網(wǎng)頁(yè)中加載jQuery函數(shù)庫(kù)以后,就可以使用jQuery對(duì)象了。jQuery的全部方法,都定義在這個(gè)對(duì)象上面。

var listItems = jQuery('li');
// or
var listItems = $('li');

上面兩行代碼是等價(jià)的,表示選中網(wǎng)頁(yè)中所有的li元素。

jQuery構(gòu)造函數(shù)

jQuery對(duì)象本質(zhì)上是一個(gè)構(gòu)造函數(shù),主要作用是返回jQuery對(duì)象的實(shí)例。比如,上面代碼表面上是選中l(wèi)i元素,實(shí)際上是返回對(duì)應(yīng)于li元素的jQuery實(shí)例。因?yàn)橹挥羞@樣,才能在DOM對(duì)象上使用jQuery提供的各種方法。

$('body').nodeType
// undefined

$('body') instanceof jQuery
// true

上面代碼表示,由于jQuery返回的不是DOM對(duì)象,所以沒有DOM屬性nodeType。它返回的是jQuery對(duì)象的實(shí)例。

(1)CSS選擇器作為參數(shù)

jQuery構(gòu)造函數(shù)的參數(shù),主要是CSS選擇器,就像上面的那個(gè)例子。下面是另外一些CSS選擇器的例子。

$("*")
$("#lastname")
$(".intro")
$("h1,div,p")
$("p:last")
$("tr:even")
$("p:first-child")
$("p:nth-of-type(2)")
$("div + p")
$("div:has(p)")
$(":empty")
$("[title^='Tom']")

本書不講解CSS選擇器,請(qǐng)讀者參考有關(guān)書籍和jQuery文檔。

(2)DOM對(duì)象作為參數(shù)

jQuery構(gòu)造函數(shù)的參數(shù),還可以是DOM對(duì)象。它也會(huì)被轉(zhuǎn)為jQuery對(duì)象的實(shí)例。

$(document.body) instanceof jQuery
// true

上面代碼中,jQuery的參數(shù)不是CSS選擇器,而是一個(gè)DOM對(duì)象,返回的依然是jQuery對(duì)象的實(shí)例。

如果有多個(gè)DOM元素要轉(zhuǎn)為jQuery對(duì)象的實(shí)例,可以把DOM元素放在一個(gè)數(shù)組里,輸入jQuery構(gòu)造函數(shù)。

$([document.body, document.head])

(3)HTML代碼作為參數(shù)

如果直接在jQuery構(gòu)造函數(shù)中輸入HTML代碼,返回的也是jQuery實(shí)例。

$('<li class="greet">test</li>')

上面代碼從HTML代碼生成了一個(gè)jQuery實(shí)例,它與從CSS選擇器生成的jQuery實(shí)例完全一樣。唯一的區(qū)別就是,它對(duì)應(yīng)的DOM結(jié)構(gòu)不屬于當(dāng)前文檔。

上面代碼也可以寫成下面這樣。

$( '<li>', {
  html: 'test',
  'class': 'greet'
});

上面代碼中,由于class是javaScript的保留字,所以只能放在引號(hào)中。

通常來(lái)說(shuō),上面第二種寫法是更好的寫法。

$('<input class="form-control" type="hidden" name="foo" value="bar" />')

// 相當(dāng)于
$('<input/>', {
    class: 'form-control',
    type: 'hidden',
    name: 'foo',
    value: 'bar'
})

// 或者
$('<input/>')
.addClass('form-control')
.attr('type', 'hidden')
.attr('name', 'foo')
.val('bar')

(4)第二個(gè)參數(shù)

默認(rèn)情況下,jQuery將文檔的根元素(html)作為尋找匹配對(duì)象的起點(diǎn)。如果要指定某個(gè)網(wǎng)頁(yè)元素(比如某個(gè)div元素)作為尋找的起點(diǎn),可以將它放在jQuery函數(shù)的第二個(gè)參數(shù)。

$('li', someElement);

上面代碼表示,只尋找屬于someElement對(duì)象下屬的li元素。someElement可以是jQuery對(duì)象的實(shí)例,也可以是DOM對(duì)象。

jQuery構(gòu)造函數(shù)返回的結(jié)果集

jQuery的核心思想是“先選中某些網(wǎng)頁(yè)元素,然后對(duì)其進(jìn)行某種處理”(find something, do something),也就是說(shuō),先選擇后處理,這是jQuery的基本操作模式。所以,絕大多數(shù)jQuery操作都是從選擇器開始的,返回一個(gè)選中的結(jié)果集。

(1)length屬性

jQuery對(duì)象返回的結(jié)果集是一個(gè)類似數(shù)組的對(duì)象,包含了所有被選中的網(wǎng)頁(yè)元素。查看該對(duì)象的length屬性,可以知道到底選中了多少個(gè)結(jié)果。

if ( $('li').length === 0 ) {
    console.log('不含li元素');
}

上面代碼表示,如果網(wǎng)頁(yè)沒有l(wèi)i元素,則返回對(duì)象的length屬性等于0。這就是測(cè)試有沒有選中的標(biāo)準(zhǔn)方法。

所以,如果想知道jQuery有沒有選中相應(yīng)的元素,不能寫成下面這樣。

if ($('div.foo')) { ... }

因?yàn)椴还苡袥]有選中,jQuery構(gòu)造函數(shù)總是返回一個(gè)實(shí)例對(duì)象,而對(duì)象的布爾值永遠(yuǎn)是true。使用length屬性才是判斷有沒有選中的正確方法。

if ($('div.foo').length) { ... }

(2)下標(biāo)運(yùn)算符

jQuery選擇器返回的是一個(gè)類似數(shù)組的對(duì)象。但是,使用下標(biāo)運(yùn)算符取出的單個(gè)對(duì)象,并不是jQuery對(duì)象的實(shí)例,而是一個(gè)DOM對(duì)象。

$('li')[0] instanceof jQuery // false
$('li')[0] instanceof Element // true

上面代碼表示,下標(biāo)運(yùn)算符取出的是Element節(jié)點(diǎn)的實(shí)例。所以,通常使用下標(biāo)運(yùn)算符將jQuery實(shí)例轉(zhuǎn)回DOM對(duì)象。

(3)is方法

is方法返回一個(gè)布爾值,表示選中的結(jié)果是否符合某個(gè)條件。這個(gè)用來(lái)驗(yàn)證的條件,可以是CSS選擇器,也可以是一個(gè)函數(shù),或者DOM元素和jQuery實(shí)例。

$('li').is('li') // true

$('li').is($('.item')) 

$('li').is(document.querySelector('li'))

$('li').is(function() {
      return $("strong", this).length === 0;
});

(4)get方法

jQuery實(shí)例的get方法是下標(biāo)運(yùn)算符的另一種寫法。

$('li').get(0) instanceof Element // true

(5)eq方法

如果想要在結(jié)果集取出一個(gè)jQuery對(duì)象的實(shí)例,不需要取出DOM對(duì)象,則使用eq方法,它的參數(shù)是實(shí)例在結(jié)果集中的位置(從0開始)。

$('li').eq(0) instanceof jQuery // true

由于eq方法返回的是jQuery的實(shí)例,所以可以在返回結(jié)果上使用jQuery實(shí)例對(duì)象的方法。

(6)each方法,map方法

這兩個(gè)方法用于遍歷結(jié)果集,對(duì)每一個(gè)成員進(jìn)行某種操作。

each方法接受一個(gè)函數(shù)作為參數(shù),依次處理集合中的每一個(gè)元素。

$('li').each(function( index, element) {
  $(element).prepend( '<em>' + index + ': </em>' );
});

// <li>Hello</li>
// <li>World</li>
// 變?yōu)?// <li><em>0: </em>Hello</li>
// <li><em>1: </em>World</li>

從上面代碼可以看出,作為each方法參數(shù)的函數(shù),本身有兩個(gè)參數(shù),第一個(gè)是當(dāng)前元素在集合中的位置,第二個(gè)是當(dāng)前元素對(duì)應(yīng)的DOM對(duì)象。

map方法的用法與each方法完全一樣,區(qū)別在于each方法沒有返回值,只是對(duì)每一個(gè)元素執(zhí)行某種操作,而map方法返回一個(gè)新的jQuery對(duì)象。

$("input").map(function (index, element){
    return $(this).val();
})
.get()
.join(", ")

上面代碼表示,將所有input元素依次取出值,然后通過(guò)get方法得到一個(gè)包含這些值的數(shù)組,最后通過(guò)數(shù)組的join方法返回一個(gè)逗號(hào)分割的字符串。

(8)內(nèi)置循環(huán)

jQuery默認(rèn)對(duì)當(dāng)前結(jié)果集進(jìn)行循環(huán)處理,所以如果直接使用jQuery內(nèi)置的某種方法,each和map方法是不必要的。

$(".class").addClass("highlight");

上面代碼會(huì)執(zhí)行一個(gè)內(nèi)部循環(huán),對(duì)每一個(gè)選中的元素進(jìn)行addClass操作。由于這個(gè)原因,對(duì)上面操作加上each方法是不必要的。

$(".class").each(function(index,element){
     $(element).addClass("highlight");
});

// 或者

$(".class").each(function(){
    $(this).addClass("highlight");
});

上面代碼的each方法,都是沒必要使用的。

由于內(nèi)置循環(huán)的存在,從性能考慮,應(yīng)該盡量減少不必要的操作步驟。

$(".class").css("color", "green").css("font-size", "16px");

// 應(yīng)該寫成

$(".class").css({ 
  "color": "green",
  "font-size": "16px"
});

鏈?zhǔn)讲僮?/h3>

jQuery最方便的一點(diǎn)就是,它的大部分方法返回的都是jQuery對(duì)象,因此可以鏈?zhǔn)讲僮鳌R簿褪钦f(shuō),后一個(gè)方法可以緊跟著寫在前一個(gè)方法后面。

$('li').click(function (){
    $(this).addClass('clicked');
})
.find('span')
.attr( 'title', 'Hover over me' );

$(document).ready()

$(document).ready方法接受一個(gè)函數(shù)作為參數(shù),將該參數(shù)作為document對(duì)象的DOMContentLoaded事件的回調(diào)函數(shù)。也就是說(shuō),當(dāng)頁(yè)面解析完成(即下載完標(biāo)簽)以后,在所有外部資源(圖片、腳本等)完成加載之前,該函數(shù)就會(huì)立刻運(yùn)行。

$( document ).ready(function() {
  console.log( 'ready!' );
});

上面代碼表示,一旦頁(yè)面完成解析,就會(huì)運(yùn)行ready方法指定的函數(shù),在控制臺(tái)顯示“ready!”。

該方法通常作為網(wǎng)頁(yè)初始化手段使用,jQuery提供了一種簡(jiǎn)寫法,就是直接把回調(diào)函數(shù)放在jQuery對(duì)象中。

$(function() {
  console.log( 'ready!' );
});

上面代碼與前一段代碼是等價(jià)的。

$.noConflict方法

jQuery使用美元符號(hào)($)指代jQuery對(duì)象。某些情況下,其他函數(shù)庫(kù)也會(huì)用到美元符號(hào),為了避免沖突,$.noConflict方法允許將美元符號(hào)與jQuery脫鉤。

<script src="https://atts.w3cschool.cn/attachments/image/cimg/script>
<script src="jquery.js"></script>
<script>$.noConflict();</script>

上面代碼就是$.noConflict方法的一般用法。在加載jQuery之后,立即調(diào)用該方法,會(huì)使得美元符號(hào)還給前面一個(gè)函數(shù)庫(kù)。這意味著,其后再調(diào)用jQuery,只能寫成jQuery.methond的形式,而不能用$.method了。

為了避免沖突,可以考慮從一開始就只使用jQuery代替美元符號(hào)。

jQuery實(shí)例對(duì)象的方法

除了上一節(jié)提到的is、get、eq方法,jQuery實(shí)例還有許多其他方法。

結(jié)果集的過(guò)濾方法

選擇器選出一組符合條件的網(wǎng)頁(yè)元素以后,jQuery提供了許多方法,可以過(guò)濾結(jié)果集,返回更準(zhǔn)確的目標(biāo)。

(1)first方法,last方法

first方法返回結(jié)果集的第一個(gè)成員,last方法返回結(jié)果集的最后一個(gè)成員。

$("li").first()

$("li").last()

(2)next方法,prev方法

next方法返回緊鄰的下一個(gè)同級(jí)元素,prev方法返回緊鄰的上一個(gè)同級(jí)元素。

$("li").first().next()
$("li").last().prev()

$("li").first().next('.item')
$("li").last().prev('.item')

如果next方法和prev方法帶有參數(shù),表示選擇符合該參數(shù)的同級(jí)元素。

(3)parent方法,parents方法,children方法

parent方法返回當(dāng)前元素的父元素,parents方法返回當(dāng)前元素的所有上級(jí)元素(直到html元素)。

$("p").parent()
$("p").parent(".selected")

$("p").parents()
$("p").parents("div")

children方法返回選中元素的所有子元素。

$("div").children()
$("div").children(".selected")

// 下面的寫法結(jié)果相同,但是效率較低

$('div > *')
$('div > .selected')

上面這三個(gè)方法都接受一個(gè)選擇器作為參數(shù)。

(4)siblings方法,nextAll方法,prevAll方法

siblings方法返回當(dāng)前元素的所有同級(jí)元素。

$('li').first().siblings()
$('li').first().siblings('.item')

nextAll方法返回當(dāng)前元素其后的所有同級(jí)元素,prevAll方法返回當(dāng)前元素前面的所有同級(jí)元素。

$('li').first().nextAll()
$('li').last().prevAll()

(5)closest方法,find方法

closest方法返回當(dāng)前元素,以及當(dāng)前元素的所有上級(jí)元素之中,第一個(gè)符合條件的元素。find方法返回當(dāng)前元素的所有符合條件的下級(jí)元素。

$('li').closest('div')
$('div').find('li')

上面代碼中的find方法,選中所有div元素下面的li元素,等同于$('li', 'div')。由于這樣寫縮小了搜索范圍,所以要優(yōu)于$('div li')的寫法。

(6)find方法,add方法,addBack方法,end方法

add方法用于為結(jié)果集添加元素。

$('li').add('p')

addBack方法將當(dāng)前元素加回原始的結(jié)果集。

$('li').parent().addBack()

end方法用于返回原始的結(jié)果集。

$('li').first().end()

(7)filter方法,not方法,has方法

filter方法用于過(guò)濾結(jié)果集,它可以接受多種類型的參數(shù),只返回與參數(shù)一致的結(jié)果。

// 返回符合CSS選擇器的結(jié)果
$('li').filter('.item')

// 返回函數(shù)返回值為true的結(jié)果
$("li").filter(function(index) {
    return index % 2 === 1;
})

// 返回符合特定DOM對(duì)象的結(jié)果
$("li").filter(document.getElementById("unique"))

// 返回符合特定jQuery實(shí)例的結(jié)果
$("li").filter($("#unique"))

not方法的用法與filter方法完全一致,但是返回相反的結(jié)果,即過(guò)濾掉匹配項(xiàng)。

$('li').not('.item')

has方法與filter方法作用相同,但是只過(guò)濾出子元素符合條件的元素。

$("li").has("ul")

上面代碼返回具有ul子元素的li元素。

DOM相關(guān)方法

許多方法可以對(duì)DOM元素進(jìn)行處理。

(1)html方法和text方法

html方法返回該元素包含的HTML代碼,text方法返回該元素包含的文本。

假定網(wǎng)頁(yè)只含有一個(gè)p元素。

<p><em>Hello World!</em></p>

html方法和text方法的返回結(jié)果分別如下。

$('p').html()
// <em>Hello World!</em> 

$('p').text()
// Hello World!

jQuery的許多方法都是取值器(getter)與賦值器(setter)的合一,即取值和賦值都是同一個(gè)方法,不使用參數(shù)的時(shí)候?yàn)槿≈灯?,使用參?shù)的時(shí)候?yàn)橘x值器。

上面代碼的html方法和text方法都沒有參數(shù),就會(huì)當(dāng)作取值器使用,取回結(jié)果集的第一個(gè)元素所包含的內(nèi)容。如果對(duì)這兩個(gè)方法提供參數(shù),就是當(dāng)作賦值器使用,修改結(jié)果集所有成員的內(nèi)容,并返回原來(lái)的結(jié)果集,以便進(jìn)行鏈?zhǔn)讲僮鳌?/p>

$('p').html('<strong>你好</strong>')
// 網(wǎng)頁(yè)代碼變?yōu)?lt;p><strong>你好</strong></p> 

$('p').text('你好')
// 網(wǎng)頁(yè)代碼變?yōu)?lt;p>你好</p>

下面要講到的jQuery其他許多方法,都采用這種同一個(gè)方法既是取值器又是賦值器的模式。

html方法和text方法還可以接受一個(gè)函數(shù)作為參數(shù),函數(shù)的返回值就是網(wǎng)頁(yè)元素所要包含的新的代碼和文本。這個(gè)函數(shù)接受兩個(gè)參數(shù),第一個(gè)是網(wǎng)頁(yè)元素在集合中的位置,第二個(gè)參數(shù)是網(wǎng)頁(yè)元素原來(lái)的代碼或文本。

$('li').html(function (i, v){
    return (i + ': ' + v);       
})

// <li>Hello</li>
// <li>World</li>
// 變?yōu)?// <li>0: Hello</li>
// <li>1: World</li>

(2)addClass方法,removeClass方法,toggleClass方法

addClass方法用于添加一個(gè)類,removeClass方法用于移除一個(gè)類,toggleClass方法用于折疊一個(gè)類(如果無(wú)就添加,如果有就移除)。

$('li').addClass('special')
$('li').removeClass('special')
$('li').toggleClass('special')

(3)css方法

css方法用于改變CSS設(shè)置。

該方法可以作為取值器使用。

$('h1').css('fontSize');

css方法的參數(shù)是css屬性名。這里需要注意,CSS屬性名的CSS寫法和DOM寫法,兩者都可以接受,比如font-size和fontSize都行。

css方法也可以作為賦值器使用。

$('li').css('padding-left', '20px')
// 或者
$('li').css({
  'padding-left': '20px'
});

上面兩種形式都可以用于賦值,jQuery賦值器基本上都是如此。

(4)val方法

val方法返回結(jié)果集第一個(gè)元素的值,或者設(shè)置當(dāng)前結(jié)果集所有元素的值。

$('input[type="text"]').val()

$('input[type="text"]').val('new value')

(5)prop方法,attr方法

首先,這里要區(qū)分兩種屬性。

一種是網(wǎng)頁(yè)元素的屬性,比如a元素的href屬性、img元素的src屬性。這要使用attr方法讀寫。

// 讀取屬性值
$('textarea').attr(name)

//寫入屬性值
$('textarea').attr(name, val)

另一種是DOM元素的屬性,比如tagName、nodeName、nodeType等等。這要使用prop方法讀寫。

// 讀取屬性值
$('textarea').prop(name)

// 寫入屬性值
$('textarea').prop(name, val)

所以,attr方法和prop方法針對(duì)的是不同的屬性。在英語(yǔ)中,attr是attribute的縮寫,prop是property的縮寫,中文很難表達(dá)出這種差異。有時(shí),attr方法和prop方法對(duì)同一個(gè)屬性會(huì)讀到不一樣的值。比如,網(wǎng)頁(yè)上有一個(gè)單選框。

<input type="checkbox" checked="checked" />

對(duì)于checked屬性,attr方法讀到的是checked,prop方法讀到的是true。

$(input[type=checkbox]).attr("checked") // "checked"

$(input[type=checkbox]).prop("checked") // true

可以看到,attr方法讀取的是網(wǎng)頁(yè)上該屬性的值,而prop方法讀取的是DOM元素的該屬性的值,根據(jù)規(guī)范,element.checked應(yīng)該返回一個(gè)布爾值。所以,判斷單選框是否選中,要使用prop方法。事實(shí)上,不管這個(gè)單選框是否選中,attr("checked")的返回值都是checked。

if ($(elem).prop("checked")) { /*... */ };

// 下面兩種方法亦可

if ( elem.checked ) { /*...*/ };
if ( $(elem).is(":checked") ) { /*...*/ };

(6)removeProp方法,removeAttr方法

removeProp方法移除某個(gè)DOM屬性,removeAttr方法移除某個(gè)HTML屬性。

$("a").prop("oldValue",1234).removeProp('oldValue')
$('a').removeAttr("title")

(7)data方法

data方法用于在一個(gè)DOM對(duì)象上儲(chǔ)存數(shù)據(jù)。

// 儲(chǔ)存數(shù)據(jù)
$("body").data("foo", 52);

// 讀取數(shù)據(jù)
$("body").data("foo");

該方法可以在DOM節(jié)點(diǎn)上儲(chǔ)存各種類型的數(shù)據(jù)。

添加、復(fù)制和移動(dòng)網(wǎng)頁(yè)元素的方法

jQuery方法提供一系列方法,可以改變?cè)卦谖臋n中的位置。

(1)append方法,appendTo方法

append方法將參數(shù)中的元素插入當(dāng)前元素的尾部。

$("div").append("<p>World</p>")

// <div>Hello </div>
// 變?yōu)?// <div>Hello <p>World</p></div>

appendTo方法將當(dāng)前元素插入?yún)?shù)中的元素尾部。

$("<p>World</p>").appendTo("div")

上面代碼返回與前一個(gè)例子一樣的結(jié)果。

(2)prepend方法,prependTo方法

prepend方法將參數(shù)中的元素,變?yōu)楫?dāng)前元素的第一個(gè)子元素。

$("p").prepend("Hello ")

// <p>World</p>
// 變?yōu)?// <p>Hello World</p>

如果prepend方法的參數(shù)不是新生成的元素,而是當(dāng)前頁(yè)面已存在的元素,則會(huì)產(chǎn)生移動(dòng)元素的效果。

$("p").prepend("strong")

// <strong>Hello </strong><p>World</p>
// 變?yōu)?// <p><strong>Hello </strong>World</p>

上面代碼運(yùn)行后,strong元素的位置將發(fā)生移動(dòng),而不是克隆一個(gè)新的strong元素。不過(guò),如果當(dāng)前結(jié)果集包含多個(gè)元素,則除了第一個(gè)以后,后面的p元素都將插入一個(gè)克隆的strong子元素。

prependTo方法將當(dāng)前元素變?yōu)閰?shù)中的元素的第一個(gè)子元素。

$("<p></p>").prependTo("div")

// <div></div>
// 變?yōu)?// <div><p></p></div>

(3)after方法,insertAfter方法

after方法將參數(shù)中的元素插在當(dāng)前元素后面。

$("div").after("<p></p>")

// <div></div>
// 變?yōu)?// <div></div><p></p>

insertAfter方法將當(dāng)前元素插在參數(shù)中的元素后面。

$("<p></p>").insertAfter("div")

上面代碼返回與前一個(gè)例子一樣的結(jié)果。

(4)before方法,insertBefore方法

before方法將參數(shù)中的元素插在當(dāng)前元素的前面。

$("div").before("<p></p>")

// <div></div>
// 變?yōu)?// <p></p><div></div>

insertBefore方法將當(dāng)前元素插在參數(shù)中的元素的前面。

$("<p></p>").insertBefore("div")

上面代碼返回與前一個(gè)例子一樣的結(jié)果。

(5)wrap方法,wrapAll方法,unwrap方法,wrapInner方法

wrap方法將參數(shù)中的元素變成當(dāng)前元素的父元素。

$("p").wrap("<div></div>")

// <p></p>
// 變?yōu)?// <div><p></p></div>

wrap方法的參數(shù)還可以是一個(gè)函數(shù)。

$("p").wrap(function() {
  return "<div></div>";
})

上面代碼返回與前一個(gè)例子一樣的結(jié)果。

wrapAll方法為結(jié)果集的所有元素,添加一個(gè)共同的父元素。

$("p").wrapAll("<div></div>")

// <p></p><p></p>
// 變?yōu)?// <div><p></p><p></p></div>

unwrap方法移除當(dāng)前元素的父元素。

$("p").unwrap()

// <div><p></p></div>
// 變?yōu)?// <p></p>

wrapInner方法為當(dāng)前元素的所有子元素,添加一個(gè)父元素。

$("p").wrapInner('<strong></strong>')

// <p>Hello</p>
// 變?yōu)?// <p><strong>Hello</strong></p>

(6)clone方法

clone方法克隆當(dāng)前元素。

var clones = $('li').clone();

對(duì)于那些有id屬性的節(jié)點(diǎn),clone方法會(huì)連id屬性一起克隆。所以,要把克隆的節(jié)點(diǎn)插入文檔的時(shí)候,務(wù)必要修改或移除id屬性。

(7)remove方法,detach方法,replaceWith方法

remove方法移除并返回一個(gè)元素,取消該元素上所有事件的綁定。detach方法也是移除并返回一個(gè)元素,但是不取消該元素上所有事件的綁定。

$('p').remove()
$('p').detach()

replaceWith方法用參數(shù)中的元素,替換并返回當(dāng)前元素,取消當(dāng)前元素的所有事件的綁定。

$('p').replaceWith('<div></div>')

動(dòng)畫效果方法

jQuery提供一些方法,可以很容易地顯示網(wǎng)頁(yè)動(dòng)畫效果。但是,總體上來(lái)說(shuō),它們不如CSS動(dòng)畫強(qiáng)大和節(jié)省資源,所以應(yīng)該優(yōu)先考慮使用CSS動(dòng)畫。

如果將jQuery.fx.off設(shè)為true,就可以將所有動(dòng)畫效果關(guān)閉,使得網(wǎng)頁(yè)元素的各種變化一步到位,沒有中間過(guò)渡的動(dòng)畫效果。

(1)動(dòng)畫效果的簡(jiǎn)便方法

jQuery提供以下一些動(dòng)畫效果方法。

  • show:顯示當(dāng)前元素。
  • hide:隱藏當(dāng)前元素。
  • toggle:顯示或隱藏當(dāng)前元素。
  • fadeIn:將當(dāng)前元素的不透明度(opacity)逐步提升到100%。
  • fadeOut:將當(dāng)前元素的不透明度逐步降為0%。
  • slideDown:以從上向下滑入的方式顯示當(dāng)前元素。
  • slideUp:以從下向上滑出的方式隱藏當(dāng)前元素。
  • slideToggle:以垂直滑入或滑出的方式,折疊顯示當(dāng)前元素。

上面這些方法可以不帶參數(shù)調(diào)用,也可以接受毫秒或預(yù)定義的關(guān)鍵字作為參數(shù)。

$('.hidden').show();
$('.hidden').show(300);
$('.hidden').show('slow');

上面三行代碼分別表示,以默認(rèn)速度、300毫秒、較慢的速度隱藏一個(gè)元素。

jQuery預(yù)定義的關(guān)鍵字是在jQuery.fx.speeds對(duì)象上面,可以自行改動(dòng)這些值,或者創(chuàng)造新的值。

jQuery.fx.speeds.fast = 50;
jQuery.fx.speeds.slow = 3000;
jQuery.fx.speeds.normal = 1000;

上面三行代碼重新定義fast和slow關(guān)鍵字對(duì)應(yīng)的毫秒數(shù),并且自定義了normal關(guān)鍵字,表示動(dòng)畫持續(xù)時(shí)間為1500毫秒。

你可以定義自己的關(guān)鍵字。

jQuery.fx.speeds.blazing = 30;

// 調(diào)用
$('.hidden').show('blazing');

這些方法還可以接受一個(gè)函數(shù),作為第二個(gè)參數(shù),表示動(dòng)畫結(jié)束后的回調(diào)函數(shù)。

$('p').fadeOut(300, function() {
  $(this).remove();
});

上面代碼表示,p元素以300毫秒的速度淡出,然后調(diào)用回調(diào)函數(shù),將其從DOM中移除。

(2)animate方法

上面這些動(dòng)畫效果方法,實(shí)際上都是animate方法的簡(jiǎn)便寫法。在幕后,jQuery都是統(tǒng)一使用animate方法生成各種動(dòng)畫效果。

animate方法接受三個(gè)參數(shù)。

$('div').animate({
    left: '+=50', // 增加50
    opacity: 0.25,
    fontSize: '12px'
  },
  300, // 持續(xù)事件
  function() { // 回調(diào)函數(shù)
     console.log('done!');
  }
);

上面代碼表示,animate方法的第一個(gè)參數(shù)是一個(gè)對(duì)象,表示動(dòng)畫結(jié)束時(shí)相關(guān)CSS屬性的值,第二個(gè)參數(shù)是動(dòng)畫持續(xù)的毫秒數(shù),第三個(gè)參數(shù)是動(dòng)畫結(jié)束時(shí)的回調(diào)函數(shù)。需要注意的是,第一個(gè)參數(shù)對(duì)象的成員名稱,必須與CSS屬性名稱一致,如果CSS屬性名稱帶有連字號(hào),則需要用“駱駝拼寫法”改寫。

(3)stop方法,delay方法

stop方法表示立即停止執(zhí)行當(dāng)前的動(dòng)畫。

$("#stop").click(function() {
  $(".block").stop();
});

上面代碼表示,點(diǎn)擊按鈕后,block元素的動(dòng)畫效果停止。

delay方法接受一個(gè)時(shí)間參數(shù),表示暫停多少毫秒后繼續(xù)執(zhí)行。

$("#foo").slideUp(300).delay(800).fadeIn(400)

上面代碼表示,slideUp動(dòng)畫之后,暫停800毫秒,然后繼續(xù)執(zhí)行fadeIn動(dòng)畫。

其他方法

jQuery還提供一些供特定元素使用的方法。

serialize方法用于將表單元素的值,轉(zhuǎn)為url使用的查詢字符串。

$( "form" ).on( "submit", function( event ) {
  event.preventDefault();
  console.log( $( this ).serialize() );
});
// single=Single&multiple=Multiple&check=check2&radio=radio1

serializeArray方法用于將表單元素的值轉(zhuǎn)為數(shù)組。

$("form").submit(function (event){
  console.log($(this).serializeArray());
  event.preventDefault();
});
// [
//     {name : 'field1', value : 123},
//     {name : 'field2', value : 'hello world'}
// ]

事件處理

事件綁定的簡(jiǎn)便方法

jQuery提供一系列方法,允許直接為常見事件綁定回調(diào)函數(shù)。比如,click方法可以為一個(gè)元素綁定click事件的回調(diào)函數(shù)。

$('li').click(function (e){
  console.log($(this).text());
});

上面代碼為li元素綁定click事件的回調(diào)函數(shù),點(diǎn)擊后在控制臺(tái)顯示li元素包含的文本。

這樣綁定事件的簡(jiǎn)便方法有如下一些:

  • click
  • keydown
  • keypress
  • keyup
  • mouseover
  • mouseout
  • mouseenter
  • mouseleave
  • scroll
  • focus
  • blur
  • resize
  • hover

如果不帶參數(shù)調(diào)用這些方法,就是觸發(fā)相應(yīng)的事件,從而引發(fā)回調(diào)函數(shù)的運(yùn)行。

$('li').click()

上面代碼將觸發(fā)click事件的回調(diào)函數(shù)。

需要注意的是,通過(guò)這種方法觸發(fā)回調(diào)函數(shù),將不會(huì)引發(fā)瀏覽器對(duì)該事件的默認(rèn)行為。比如,對(duì)a元素調(diào)用click方法,將只觸發(fā)事先綁定的回調(diào)函數(shù),而不會(huì)導(dǎo)致瀏覽器將頁(yè)面導(dǎo)向href屬性指定的網(wǎng)址。

下面是一個(gè)捕捉用戶按下escape鍵的函數(shù)。

$(document).keyup(function(e) {
  if (e.keyCode == 27) {
    $('body').toggleClass('show-nav');
    // $('body').removeClass('show-nav');
  }
});

上面代碼中,用戶按下escape鍵,jQuery就會(huì)為body元素添加/去除名為show-nav的class。

hover方法需要特別說(shuō)明。它接受兩個(gè)回調(diào)函數(shù)作為參數(shù),分別代表mouseenter和mouseleave事件的回調(diào)函數(shù)。

$(selector).hover(handlerIn, handlerOut)

// 等同于

$(selector).mouseenter(handlerIn).mouseleave(handlerOut)

on方法,trigger方法,off方法

除了簡(jiǎn)便方法,jQuery還提供事件處理的通用方法。

(1)on方法

on方法是jQuery事件綁定的統(tǒng)一接口。事件綁定的那些簡(jiǎn)便方法,其實(shí)都是on方法的簡(jiǎn)寫形式。

on方法接受兩個(gè)參數(shù),第一個(gè)是事件名稱,第二個(gè)是回調(diào)函數(shù)。

$('li').on('click', function (e){
  console.log($(this).text());
});

上面代碼為li元素綁定click事件的回調(diào)函數(shù)。

注意,在回調(diào)函數(shù)內(nèi)部,this關(guān)鍵字指的是發(fā)生該事件的DOM對(duì)象。為了使用jQuery提供的方法,必須將DOM對(duì)象轉(zhuǎn)為jQuery對(duì)象,因此寫成$(this)。

on方法允許一次為多個(gè)事件指定同樣的回調(diào)函數(shù)。

$('input[type="text"]').on('focus blur', function (){
  console.log('focus or blur');
});

上面代碼為文本框的focus和blur事件綁定同一個(gè)回調(diào)函數(shù)。

on方法還可以為當(dāng)前元素的某一個(gè)子元素,添加回調(diào)函數(shù)。

$('ul').on('click', 'li', function (e){
  console.log(this);
});

上面代碼為ul的子元素li綁定click事件的回調(diào)函數(shù)。采用這種寫法時(shí),on方法接受三個(gè)參數(shù),子元素選擇器作為第二個(gè)參數(shù),夾在事件名稱和回調(diào)函數(shù)之間。

這種寫法有兩個(gè)好處。首先,click事件還是在ul元素上觸發(fā)回調(diào)函數(shù),但是會(huì)檢查event對(duì)象的target屬性是否為li子元素,如果為true,再調(diào)用回調(diào)函數(shù)。這樣就比為li元素一一綁定回調(diào)函數(shù),節(jié)省了內(nèi)存空間。其次,這種綁定的回調(diào)函數(shù),對(duì)于在綁定后生成的li元素依然有效。

on方法還允許向回調(diào)函數(shù)傳入數(shù)據(jù)。

$("ul" ).on("click", {name: "張三"}, function (event){
    console.log(event.data.name);
});

上面代碼在發(fā)生click事件之后,會(huì)通過(guò)event對(duì)象的data屬性,在控制臺(tái)打印出所傳入的數(shù)據(jù)(即“張三”)。

(2)trigger方法

trigger方法用于觸發(fā)回調(diào)函數(shù),它的參數(shù)就是事件的名稱。

$('li').trigger('click')

上面代碼觸發(fā)li元素的click事件回調(diào)函數(shù)。與那些簡(jiǎn)便方法一樣,trigger方法只觸發(fā)回調(diào)函數(shù),而不會(huì)引發(fā)瀏覽器的默認(rèn)行為。

(3)off方法

off方法用于移除事件的回調(diào)函數(shù)。

$('li').off('click')

上面代碼移除li元素所有的click事件回調(diào)函數(shù)。

(4)事件的名稱空間

同一個(gè)事件有時(shí)綁定了多個(gè)回調(diào)函數(shù),這時(shí)如果想移除其中的一個(gè)回調(diào)函數(shù),可以采用“名稱空間”的方式,即為每一個(gè)回調(diào)函數(shù)指定一個(gè)二級(jí)事件名,然后再用off方法移除這個(gè)二級(jí)事件的回調(diào)函數(shù)。

$('li').on('click.logging', function (){
  console.log('click.logging callback removed');
});

$('li').off('click.logging');

上面代碼為li元素定義了二級(jí)事件click.logging的回調(diào)函數(shù),click.logging屬于click名稱空間,當(dāng)發(fā)生click事件時(shí)會(huì)觸發(fā)該回調(diào)函數(shù)。將click.logging作為off方法的參數(shù),就會(huì)移除這個(gè)回調(diào)函數(shù),但是對(duì)其他click事件的回調(diào)函數(shù)沒有影響。

trigger方法也適用帶名稱空間的事件。

$('li').trigger('click.logging')

event對(duì)象

當(dāng)回調(diào)函數(shù)被觸發(fā)后,它們的參數(shù)通常是一個(gè)事件對(duì)象event。

$(document).on('click', function (e){
    // ...
});

上面代碼的回調(diào)函數(shù)的參數(shù)e,就代表事件對(duì)象event。

event對(duì)象有以下屬性:

  • type:事件類型,比如click。
  • which:觸發(fā)該事件的鼠標(biāo)按鈕或鍵盤的鍵。
  • target:事件發(fā)生的初始對(duì)象。
  • data:傳入事件對(duì)象的數(shù)據(jù)。
  • pageX:事件發(fā)生時(shí),鼠標(biāo)位置的水平坐標(biāo)(相對(duì)于頁(yè)面左上角)。
  • pageY:事件發(fā)生時(shí),鼠標(biāo)位置的垂直坐標(biāo)(相對(duì)于頁(yè)面左上角)。

event對(duì)象有以下方法:

  • preventDefault:取消瀏覽器默認(rèn)行為。
  • stopPropagation:阻止事件向上層元素傳播。

一次性事件

one方法指定一次性的回調(diào)函數(shù),即這個(gè)函數(shù)只能運(yùn)行一次。這對(duì)提交表單很有用。

$("#button").one( "click", function() { return false; } );

one方法本質(zhì)上是回調(diào)函數(shù)運(yùn)行一次,即解除對(duì)事件的監(jiān)聽。

document.getElementById("#button").addEventListener("click", handler);

function handler(e) {
    e.target.removeEventListener(e.type, arguments.callee);
    return false;
}

上面的代碼在點(diǎn)擊一次以后,取消了對(duì)click事件的監(jiān)聽。如果有特殊需要,可以設(shè)定點(diǎn)擊2次或3次之后取消監(jiān)聽,這都是可以的。

參考鏈接

以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)