JQuery

  • 選擇器
    選擇器是jQuery的核心。

按ID查找
如果某個(gè)DOM節(jié)點(diǎn)有id屬性枝嘶,利用jQuery查找如下:
// 查找<div id="abc">:
var div = $('#abc');
注意帘饶,#abc以#開頭。返回的對(duì)象是jQuery對(duì)象群扶。
什么是jQuery對(duì)象及刻?jQuery對(duì)象類似數(shù)組,它的每個(gè)元素都是一個(gè)引用了DOM節(jié)點(diǎn)的對(duì)象竞阐。
以上面的查找為例缴饭,如果id為abc的<div>存在,返回的jQuery對(duì)象如下:
[<div id="abc">...</div>]
如果id為abc的<div>不存在骆莹,返回的jQuery對(duì)象如下:
[]
總之jQuery的選擇器不會(huì)返回undefined或者null颗搂,這樣的好處是你不必在下一行判斷if (div === undefined)。
jQuery對(duì)象和DOM對(duì)象之間可以互相轉(zhuǎn)化:
var div = $('#abc'); // jQuery對(duì)象
var divDom = div.get(0); // 假設(shè)存在div幕垦,獲取第1個(gè)DOM元素
var another = $(divDom); // 重新把DOM包裝為jQuery對(duì)象
通常情況下你不需要獲取DOM對(duì)象丢氢,直接使用jQuery對(duì)象更加方便。如果你拿到了一個(gè)DOM對(duì)象先改,那可以簡(jiǎn)單地調(diào)用$(aDomObject)把它變成jQuery對(duì)象疚察,這樣就可以方便地使用jQuery的API了。
按tag查找
按tag查找只需要寫上tag名稱就可以了:
var ps = $('p'); // 返回所有<p>節(jié)點(diǎn)
ps.length; // 數(shù)一數(shù)頁面有多少個(gè)<p>節(jié)點(diǎn)
按class查找(點(diǎn).)
按class查找注意在class名稱前加一個(gè).:
var a = $('.red'); // 所有節(jié)點(diǎn)包含`class="red"`都將返回
// 例如:
// <div class="red">...</div>
// <p class="green red">...</p>
通常很多節(jié)點(diǎn)有多個(gè)class仇奶,我們可以查找同時(shí)包含red和green的節(jié)點(diǎn):
var a = $('.red.green'); // 注意沒有空格貌嫡!
// 符合條件的節(jié)點(diǎn):
// <div class="red green">...</div>
// <div class="blue green red">...</div>
按屬性查找(中括號(hào)[])
一個(gè)DOM節(jié)點(diǎn)除了id和class外還可以有很多屬性,很多時(shí)候按屬性查找會(huì)非常方便该溯,比如在一個(gè)表單中按屬性來查找:
var email = $('[name=email]'); // 找出<??? name="email">
var passwordInput = $('[type=password]'); // 找出<??? type="password">
var a = $('[items="A B"]'); // 找出<??? items="A B">
當(dāng)屬性的值包含空格等特殊字符時(shí)岛抄,需要用雙引號(hào)括起來。
按屬性查找還可以使用前綴查找或者后綴查找(中括號(hào)[]+^或$)
var icons = $('[name^=icon]'); // 找出所有name屬性值以icon開頭的DOM
// 例如: name="icon-1", name="icon-2"
var names = $('[name$=with]'); // 找出所有name屬性值以with結(jié)尾的DOM
// 例如: name="startswith", name="endswith"
這個(gè)方法尤其適合通過class屬性查找朗伶,且不受class包含多個(gè)名稱的影響:
var icons = $('[class^="icon-"]'); // 找出所有class包含至少一個(gè)以`icon-`開頭的DOM
// 例如: class="icon-clock", class="abc icon-home"
組合查找(標(biāo)簽+中括號(hào)[])
組合查找就是把上述簡(jiǎn)單選擇器組合起來使用弦撩。如果我們查找$('[name=email]'),很可能把表單外的<div name="email">也找出來论皆,但我們只希望查找<input>益楼,就可以這么寫:
var emailInput = $('input[name=email]'); // 不會(huì)找出<div name="email">
同樣的,根據(jù)tag和class來組合查找也很常見:
var tr = $('tr.red'); // 找出<tr class="red ...">...</tr>
多項(xiàng)選擇器(逗號(hào),)
多項(xiàng)選擇器就是把多個(gè)選擇器用,組合起來一塊選:
$('p,div'); // 把<p>和<div>都選出來
$('p.red,p.green'); // 把<p class="red">和<p class="green">都選出來
要注意的是点晴,選出來的元素是按照它們?cè)贖TML中出現(xiàn)的順序排列的感凤,而且不會(huì)有重復(fù)元素。例如粒督,<p class="red green">不會(huì)被上面的$('p.red,p.green')選擇兩次陪竿。
層級(jí)選擇器(空格)
如果兩個(gè)DOM元素具有層級(jí)關(guān)系,就可以用$('ancestor descendant')來選擇,層級(jí)之間用空格隔開族跛。
子選擇器(大于號(hào)>)
子選擇器$('parent>child')類似層級(jí)選擇器闰挡,但是限定了層級(jí)關(guān)系必須是父子關(guān)系,就是<child>節(jié)點(diǎn)必須是<parent>節(jié)點(diǎn)的直屬子節(jié)點(diǎn)礁哄。
過濾器(冒號(hào):)
過濾器一般不單獨(dú)使用长酗,它通常附加在選擇器上,幫助我們更精確地定位元素桐绒。觀察過濾器的效果:
$('ul.lang li'); // 選出JavaScript夺脾、Python和Lua 3個(gè)節(jié)點(diǎn)
$('ul.lang li:first-child'); // 僅選出JavaScript
$('ul.lang li:last-child'); // 僅選出Lua
$('ul.lang li:nth-child(2)'); // 選出第N個(gè)元素,N從1開始
$('ul.lang li:nth-child(even)'); // 選出序號(hào)為偶數(shù)的元素
$('ul.lang li:nth-child(odd)'); // 選出序號(hào)為奇數(shù)的元素
針對(duì)表單元素茉继,jQuery還有一組特殊的選擇器:
:input:可以選擇<input>咧叭,<textarea>,<select>和<button>烁竭;
:file:可以選擇<input type="file">菲茬,和input[type=file]一樣;
:checkbox:可以選擇復(fù)選框派撕,和input[type=checkbox]一樣生均;
:radio:可以選擇單選框,和input[type=radio]一樣腥刹;
:focus:可以選擇當(dāng)前輸入焦點(diǎn)的元素马胧,例如把光標(biāo)放到一個(gè)<input>上,用$('input:focus')就可以選出衔峰;
:checked:選擇當(dāng)前勾上的單選框和復(fù)選框佩脊,用這個(gè)選擇器可以立刻獲得用戶選擇的項(xiàng)目,如$('input[type=radio]:checked')垫卤;
:enabled:可以選擇可以正常輸入的<input>威彰、<select>等,也就是沒有灰掉的輸入穴肘;
:disabled:和:enabled正好相反歇盼,選擇那些不能輸入的。
此外评抚,jQuery還有很多有用的選擇器豹缀,例如,選出可見的或隱藏的元素:
$('div:visible'); // 所有可見的div
$('div:hidden'); // 所有隱藏的div
查找
最常見的查找是在某個(gè)節(jié)點(diǎn)的所有子節(jié)點(diǎn)中查找慨代,使用find()方法邢笙,它本身又接收一個(gè)任意的選擇器。例如如下的HTML結(jié)構(gòu):
<!-- HTML結(jié)構(gòu) -->
<ul class="lang">
    <li class="js dy">JavaScript</li>
    <li class="dy">Python</li>
    <li id="swift">Swift</li>
    <li class="dy">Scheme</li>
    <li name="haskell">Haskell</li>
</ul>
用find()查找:
var ul = $('ul.lang'); // 獲得<ul>
var dy = ul.find('.dy'); // 獲得JavaScript, Python, Scheme
var swf = ul.find('#swift'); // 獲得Swift
var hsk = ul.find('[name=haskell]'); // 獲得Haskell
如果要從當(dāng)前節(jié)點(diǎn)開始向上查找侍匙,使用parent()方法:
var swf = $('#swift'); // 獲得Swift
var parent = swf.parent(); // 獲得Swift的上層節(jié)點(diǎn)<ul>
var a = swf.parent('div.red'); // 從Swift的父節(jié)點(diǎn)開始向上查找氮惯,直到找到某個(gè)符合條件的節(jié)點(diǎn)并返回
對(duì)于位于同一層級(jí)的節(jié)點(diǎn),可以通過next()和prev()方法,例如:
當(dāng)我們已經(jīng)拿到Swift節(jié)點(diǎn)后:
var swift = $('#swift');
swift.next(); // Scheme
swift.next('[name=haskell]'); // Haskell妇汗,因?yàn)镠askell是后續(xù)第一個(gè)符合選擇器條件的節(jié)點(diǎn)
swift.prev(); // Python
swift.prev('.js'); // JavaScript帘不,因?yàn)镴avaScript是往前第一個(gè)符合選擇器條件的節(jié)點(diǎn)
過濾
和函數(shù)式編程的map、filter類似杨箭,jQuery對(duì)象也有類似的方法厌均。
filter()方法可以過濾掉不符合選擇器條件的節(jié)點(diǎn):
var langs = $('ul.lang li'); // 拿到JavaScript, Python, Swift, Scheme和Haskell
var a = langs.filter('.dy'); // 拿到JavaScript, Python, Scheme
或者傳入一個(gè)函數(shù),要特別注意函數(shù)內(nèi)部的this被綁定為DOM對(duì)象告唆,不是jQuery對(duì)象:
var langs = $('ul.lang li'); // 拿到JavaScript, Python, Swift, Scheme和Haskell
langs.filter(function () {
    return this.innerHTML.indexOf('S') === 0; // 返回S開頭的節(jié)點(diǎn)
}); // 拿到Swift, Scheme
map()方法把一個(gè)jQuery對(duì)象包含的若干DOM節(jié)點(diǎn)轉(zhuǎn)化為其他對(duì)象:
var langs = $('ul.lang li'); // 拿到JavaScript, Python, Swift, Scheme和Haskell
var arr = langs.map(function () {
    return this.innerHTML;
}).get(); // 用get()拿到包含string的Array:['JavaScript', 'Python', 'Swift', 'Scheme', 'Haskell']
此外,一個(gè)jQuery對(duì)象如果包含了不止一個(gè)DOM節(jié)點(diǎn)晶密,first()擒悬、last()和slice()方法可以返回一個(gè)新的jQuery對(duì)象,把不需要的DOM節(jié)點(diǎn)去掉:
var langs = $('ul.lang li'); // 拿到JavaScript, Python, Swift, Scheme和Haskell
var js = langs.first(); // JavaScript稻艰,相當(dāng)于$('ul.lang li:first-child')
var haskell = langs.last(); // Haskell, 相當(dāng)于$('ul.lang li:last-child')
var sub = langs.slice(2, 4); // Swift, Scheme, 參數(shù)和數(shù)組的slice()方法一致
操作DOM
修改Text和HTML
jQuery對(duì)象的text()和html()方法分別獲取節(jié)點(diǎn)的文本和原始HTML文本懂牧,例如,如下的HTML結(jié)構(gòu):
<!-- HTML結(jié)構(gòu) -->
<ul id="test-ul">
    <li class="js">JavaScript</li>
    <li name="book">Java & JavaScript</li>
</ul>
分別獲取文本和HTML:
$('#test-ul li[name=book]').text(); // 'Java & JavaScript'
$('#test-ul li[name=book]').html(); // 'Java & JavaScript'
如何設(shè)置文本或HTML尊勿?jQuery的API設(shè)計(jì)非常巧妙:無參數(shù)調(diào)用text()是獲取文本僧凤,傳入?yún)?shù)就變成設(shè)置文本,HTML也是類似操作
一個(gè)jQuery對(duì)象可以包含0個(gè)或任意個(gè)DOM對(duì)象元扔,它的方法實(shí)際上會(huì)作用在對(duì)應(yīng)的每個(gè)DOM節(jié)點(diǎn)上躯保。在上面的例子中試試:
$('#test-ul li').text('JS'); // 是不是兩個(gè)節(jié)點(diǎn)都變成了JS?
所以jQuery對(duì)象的另一個(gè)好處是我們可以執(zhí)行一個(gè)操作澎语,作用在對(duì)應(yīng)的一組DOM節(jié)點(diǎn)上途事。即使選擇器沒有返回任何DOM節(jié)點(diǎn),調(diào)用jQuery對(duì)象的方法仍然不會(huì)報(bào)錯(cuò):
// 如果不存在id為not-exist的節(jié)點(diǎn):
$('#not-exist').text('Hello'); // 代碼不報(bào)錯(cuò)擅羞,沒有節(jié)點(diǎn)被設(shè)置為'Hello'
這意味著jQuery幫你免去了許多if語句尸变。
修改CSS
jQuery對(duì)象有“批量操作”的特點(diǎn),這用于修改CSS實(shí)在是太方便了减俏≌倮茫考慮下面的HTML結(jié)構(gòu):
<!-- HTML結(jié)構(gòu) -->
<ul id="test-css">
    <li class="lang dy"><span>JavaScript</span></li>
    <li class="lang"><span>Java</span></li>
    <li class="lang dy"><span>Python</span></li>
    <li class="lang"><span>Swift</span></li>
    <li class="lang dy"><span>Scheme</span></li>
</ul>
注意,jQuery對(duì)象的所有方法都返回一個(gè)jQuery對(duì)象(可能是新的也可能是自身)娃承,這樣我們可以進(jìn)行鏈?zhǔn)秸{(diào)用奏夫,非常方便。
jQuery對(duì)象的css()方法可以這么用:
var div = $('#test-div');
div.css('color'); // '#000033', 獲取CSS屬性
div.css('color', '#336699'); // 設(shè)置CSS屬性
div.css('color', ''); // 清除CSS屬性
為了和JavaScript保持一致历筝,CSS屬性可以用'background-color'和'backgroundColor'兩種格式桶蛔。
css()方法將作用于DOM節(jié)點(diǎn)的style屬性,具有最高優(yōu)先級(jí)漫谷。如果要修改class屬性仔雷,可以用jQuery提供的下列方法:
var div = $('#test-div');
div.hasClass('highlight'); // false, class是否包含highlight
div.addClass('highlight'); // 添加highlight這個(gè)class
div.removeClass('highlight'); // 刪除highlight這個(gè)class
顯示和隱藏DOM
要隱藏一個(gè)DOM,我們可以設(shè)置CSS的display屬性為none碟婆,利用css()方法就可以實(shí)現(xiàn)电抚。不過,要顯示這個(gè)DOM就需要恢復(fù)原有的display屬性竖共,這就得先記下來原有的display屬性到底是block還是inline還是別的值蝙叛。
考慮到顯示和隱藏DOM元素使用非常普遍,jQuery直接提供show()和hide()方法公给,我們不用關(guān)心它是如何修改display屬性的借帘,總之它能正常工作:
var a = $('a[target=_blank]');
a.hide(); // 隱藏
a.show(); // 顯示
注意,隱藏DOM節(jié)點(diǎn)并未改變DOM樹的結(jié)構(gòu)淌铐,它只影響DOM節(jié)點(diǎn)的顯示肺然。這和刪除DOM節(jié)點(diǎn)是不同的。
獲取DOM信息
利用jQuery對(duì)象的若干方法腿准,我們直接可以獲取DOM的高寬等信息际起,而無需針對(duì)不同瀏覽器編寫特定代碼:
// 瀏覽器可視窗口大小:
$(window).width(); // 800
$(window).height(); // 600
// HTML文檔大小:
$(document).width(); // 800
$(document).height(); // 3500
// 某個(gè)div的大小:
var div = $('#test-div');
div.width(); // 600
div.height(); // 300
div.width(400); // 設(shè)置CSS屬性 width: 400px,是否生效要看CSS是否有效
div.height('200px'); // 設(shè)置CSS屬性 height: 200px吐葱,是否生效要看CSS是否有效
attr()和removeAttr()方法用于操作DOM節(jié)點(diǎn)的屬性:
// <div id="test-div" name="Test" start="1">...</div>
var div = $('#test-div');
div.attr('data'); // undefined, 屬性不存在
div.attr('name'); // 'Test'
div.attr('name', 'Hello'); // div的name屬性變?yōu)?Hello'
div.removeAttr('name'); // 刪除name屬性
div.attr('name'); // undefined
prop()方法和attr()類似街望,但是HTML5規(guī)定有一種屬性在DOM節(jié)點(diǎn)中可以沒有值,只有出現(xiàn)與不出現(xiàn)兩種弟跑,例如:
<input id="test-radio" type="radio" name="test" checked value="1">
等價(jià)于:
<input id="test-radio" type="radio" name="test" checked="checked" value="1">
attr()和prop()對(duì)于屬性checked處理有所不同:
var radio = $('#test-radio');
radio.attr('checked'); // 'checked'
radio.prop('checked'); // true
prop()返回值更合理一些灾前。不過,用is()方法判斷更好:
var radio = $('#test-radio');
radio.is(':checked'); // true
類似的屬性還有selected孟辑,處理時(shí)最好用is(':selected')豫柬。
操作表單
對(duì)于表單元素,jQuery對(duì)象統(tǒng)一提供val()方法獲取和設(shè)置對(duì)應(yīng)的value屬性:
/*
    <input id="test-input" name="email" value="">
    <select id="test-select" name="city">
        <option value="BJ" selected>Beijing</option>
        <option value="SH">Shanghai</option>
        <option value="SZ">Shenzhen</option>
    </select>
    <textarea id="test-textarea">Hello</textarea>
*/
var
    input = $('#test-input'),
    select = $('#test-select'),
    textarea = $('#test-textarea');
input.val(); // 'test'
input.val('abc@example.com'); // 文本框的內(nèi)容已變?yōu)閍bc@example.com
select.val(); // 'BJ'
select.val('SH'); // 選擇框已變?yōu)镾hanghai
textarea.val(); // 'Hello'
textarea.val('Hi'); // 文本區(qū)域已更新為'Hi'
可見扑浸,一個(gè)val()就統(tǒng)一了各種輸入框的取值和賦值的問題烧给。
  • 事件

由于不同的瀏覽器綁定事件的代碼都不太一樣,所以用jQuery來寫代碼喝噪,就屏蔽了不同瀏覽器的差異础嫡,我們總是編寫相同的代碼。
舉個(gè)例子酝惧,假設(shè)要在用戶點(diǎn)擊了超鏈接時(shí)彈出提示框榴鼎,我們用jQuery這樣綁定一個(gè)click事件:
/* HTML:
 *
 * <a id="test-link" href="#0">點(diǎn)我試試</a>
 *
 */
// 獲取超鏈接的jQuery對(duì)象:
var a = $('#test-link');
a.on('click', function () {
    alert('Hello!');
});
實(shí)測(cè):點(diǎn)我試試
on方法用來綁定一個(gè)事件,我們需要傳入事件名稱和對(duì)應(yīng)的處理函數(shù)晚唇。
另一種更簡(jiǎn)化的寫法是直接調(diào)用click()方法:
a.click(function () {
    alert('Hello!');
});
兩者完全等價(jià)巫财。我們通常用后面的寫法。
jQuery能夠綁定的事件主要包括:
鼠標(biāo)事件
click: 鼠標(biāo)單擊時(shí)觸發(fā)哩陕;
dblclick:鼠標(biāo)雙擊時(shí)觸發(fā)平项;
mouseenter:鼠標(biāo)進(jìn)入時(shí)觸發(fā)赫舒;
mouseleave:鼠標(biāo)移出時(shí)觸發(fā);
mousemove:鼠標(biāo)在DOM內(nèi)部移動(dòng)時(shí)觸發(fā)闽瓢;
hover:鼠標(biāo)進(jìn)入和退出時(shí)觸發(fā)兩個(gè)函數(shù)接癌,相當(dāng)于mouseenter加上mouseleave。
鍵盤事件
鍵盤事件僅作用在當(dāng)前焦點(diǎn)的DOM上扣讼,通常是<input>和<textarea>缺猛。
keydown:鍵盤按下時(shí)觸發(fā);
keyup:鍵盤松開時(shí)觸發(fā)椭符;
keypress:按一次鍵后觸發(fā)荔燎。
其他事件
focus:當(dāng)DOM獲得焦點(diǎn)時(shí)觸發(fā);
blur:當(dāng)DOM失去焦點(diǎn)時(shí)觸發(fā)销钝;
change:當(dāng)<input>有咨、<select>或<textarea>的內(nèi)容改變時(shí)觸發(fā);
submit:當(dāng)<form>提交時(shí)觸發(fā)曙搬;
ready:當(dāng)頁面被載入并且DOM樹完成初始化后觸發(fā)。
其中鸽嫂,ready僅作用于document對(duì)象纵装。由于ready事件在DOM完成初始化后觸發(fā),且只觸發(fā)一次据某,所以非常適合用來寫其他的初始化代碼橡娄。假設(shè)我們想給一個(gè)<form>表單綁定submit事件,下面的代碼沒有預(yù)期的效果:
<html>
<head>
    <script>
        // 代碼有誤:
        $('#testForm).on('submit', function () {
            alert('submit!');
        });
    </script>
</head>
<body>
    <form id="testForm">
        ...
    </form>
</body>
因?yàn)镴avaScript在此執(zhí)行的時(shí)候癣籽,<form>尚未載入瀏覽器挽唉,所以$('#testForm)返回[],并沒有綁定事件到任何DOM上筷狼。
所以我們自己的初始化代碼必須放到document對(duì)象的ready事件中瓶籽,保證DOM已完成初始化:
<html>
<head>
    <script>
        $(document).on('ready', function () {
            $('#testForm).on('submit', function () {
                alert('submit!');
            });
        });
    </script>
</head>
<body>
    <form id="testForm">
        ...
    </form>
</body>
這樣寫就沒有問題了。因?yàn)橄嚓P(guān)代碼會(huì)在DOM樹初始化后再執(zhí)行埂材。
由于ready事件使用非常普遍塑顺,所以可以這樣簡(jiǎn)化:
$(document).ready(function () {
    // on('submit', function)也可以簡(jiǎn)化:
    $('#testForm).submit(function () {
        alert('submit!');
    });
});
甚至還可以再簡(jiǎn)化為:
$(function () {
    // init...
});
上面的這種寫法最為常見。如果你遇到$(function () {...})的形式俏险,牢記這是document對(duì)象的ready事件處理函數(shù)严拒。
完全可以反復(fù)綁定事件處理函數(shù),它們會(huì)依次執(zhí)行:
$(function () {
    console.log('init A...');
});
$(function () {
    console.log('init B...');
});
$(function () {
    console.log('init C...');
});
事件參數(shù)
有些事件竖独,如mousemove和keypress裤唠,我們需要獲取鼠標(biāo)位置和按鍵的值,否則監(jiān)聽這些事件就沒什么意義了莹痢。所有事件都會(huì)傳入Event對(duì)象作為參數(shù)种蘸,可以從Event對(duì)象上獲取到更多的信息:
$(function () {
    $('#testMouseMoveDiv').mousemove(function (e) {
        $('#testMouseMoveSpan').text('pageX = ' + e.pageX + ', pageY = ' + e.pageY);
    });
});
取消綁定
一個(gè)已被綁定的事件可以解除綁定墓赴,通過off('click', function)實(shí)現(xiàn):
function hello() {
    alert('hello!');
}
a.click(hello); // 綁定事件
// 10秒鐘后解除綁定:
setTimeout(function () {
    a.off('click', hello);
}, 10000);
需要特別注意的是,下面這種寫法是無效的:
// 綁定事件:
a.click(function () {
    alert('hello!');
});
// 解除綁定:
a.off('click', function () {
    alert('hello!');
});
這是因?yàn)閮蓚€(gè)匿名函數(shù)雖然長得一模一樣劈彪,但是它們是兩個(gè)不同的函數(shù)對(duì)象竣蹦,off('click', function () {...})無法移除已綁定的第一個(gè)匿名函數(shù)。
為了實(shí)現(xiàn)移除效果沧奴,可以使用off('click')一次性移除已綁定的click事件的所有處理函數(shù)痘括。
同理,無參數(shù)調(diào)用off()一次性移除已綁定的所有類型的事件處理函數(shù)滔吠。
事件觸發(fā)條件
一個(gè)需要注意的問題是纲菌,事件的觸發(fā)總是由用戶操作引發(fā)的。例如疮绷,我們監(jiān)控文本框的內(nèi)容改動(dòng):
var input = $('#test-input');
input.change(function () {
    console.log('changed...');
});
當(dāng)用戶在文本框中輸入時(shí)翰舌,就會(huì)觸發(fā)change事件。但是冬骚,如果用JavaScript代碼去改動(dòng)文本框的值椅贱,將不會(huì)觸發(fā)change事件:
var input = $('#test-input');
input.val('change it!'); // 無法觸發(fā)change事件
有些時(shí)候,我們希望用代碼觸發(fā)change事件只冻,可以直接調(diào)用無參數(shù)的change()方法來觸發(fā)該事件:
var input = $('#test-input');
input.val('change it!');
input.change(); // 觸發(fā)change事件
input.change()相當(dāng)于input.trigger('change')庇麦,它是trigger()方法的簡(jiǎn)寫。
為什么我們希望手動(dòng)觸發(fā)一個(gè)事件呢喜德?如果不這么做山橄,很多時(shí)候,我們就得寫兩份一模一樣的代碼舍悯。
瀏覽器安全限制
在瀏覽器中航棱,有些JavaScript代碼只有在用戶觸發(fā)下才能執(zhí)行,例如萌衬,window.open()函數(shù):
// 無法彈出新窗口饮醇,將被瀏覽器屏蔽:
$(function () {
    window.open('/');
});
這些“敏感代碼”只能由用戶操作來觸發(fā):
var button1 = $('#testPopupButton1');
var button2 = $('#testPopupButton2');
function popupTestWindow() {
    window.open('/');
}
button1.click(function () {
    popupTestWindow();
});
button2.click(function () {
    // 不立刻執(zhí)行popupTestWindow(),100毫秒后執(zhí)行:
    setTimeout(popupTestWindow, 100);
});
當(dāng)用戶點(diǎn)擊button1時(shí)秕豫,click事件被觸發(fā)驳阎,由于popupTestWindow()在click事件處理函數(shù)內(nèi)執(zhí)行,這是瀏覽器允許的馁蒂,而button2的click事件并未立刻執(zhí)行popupTestWindow()呵晚,延遲執(zhí)行的popupTestWindow()將被瀏覽器攔截。
  • 動(dòng)畫

jQuery內(nèi)置的幾種動(dòng)畫樣式:
show / hide/toggle
直接以無參數(shù)形式調(diào)用show()和hide()沫屡,會(huì)顯示和隱藏DOM元素饵隙。但是,只要傳遞一個(gè)時(shí)間參數(shù)進(jìn)去沮脖,就變成了動(dòng)畫:
var div = $('#test-show-hide');
div.hide(3000); // 在3秒鐘內(nèi)逐漸消失
時(shí)間以毫秒為單位金矛,但也可以是'slow'芯急,'fast'這些字符串:
var div = $('#test-show-hide');
div.show('slow'); // 在0.6秒鐘內(nèi)逐漸顯示
toggle()方法則根據(jù)當(dāng)前狀態(tài)決定是show()還是hide()。
slideUp / slideDown/slideToggle
你可能已經(jīng)看出來了驶俊,show()和hide()是從左上角逐漸展開或收縮的娶耍,而slideUp()和slideDown()則是在垂直方向逐漸展開或收縮的。
slideUp()把一個(gè)可見的DOM元素收起來饼酿,效果跟拉上窗簾似的榕酒,slideDown()相反,而slideToggle()則根據(jù)元素是否可見來決定下一步動(dòng)作:
var div = $('#test-slide');
div.slideUp(3000); // 在3秒鐘內(nèi)逐漸向上消失
fadeIn / fadeOut/fadeToggle
fadeIn()和fadeOut()的動(dòng)畫效果是淡入淡出故俐,也就是通過不斷設(shè)置DOM元素的opacity屬性來實(shí)現(xiàn)想鹰,而fadeToggle()則根據(jù)元素是否可見來決定下一步動(dòng)作:
var div = $('#test-fade');
div.fadeOut('slow'); // 在0.6秒內(nèi)淡出
自定義動(dòng)畫
如果上述動(dòng)畫效果還不能滿足你的要求,那就祭出最后大招:animate()药版,它可以實(shí)現(xiàn)任意動(dòng)畫效果辑舷,我們需要傳入的參數(shù)就是DOM元素最終的CSS狀態(tài)和時(shí)間,jQuery在時(shí)間段內(nèi)不斷調(diào)整CSS直到達(dá)到我們?cè)O(shè)定的值:
var div = $('#test-animate');
div.animate({
    opacity: 0.25,
    width: '256px',
    height: '256px'
}, 3000); // 在3秒鐘內(nèi)CSS過渡到設(shè)定值
animate()還可以再傳入一個(gè)函數(shù)槽片,當(dāng)動(dòng)畫結(jié)束時(shí)何缓,該函數(shù)將被調(diào)用:
var div = $('#test-animate');
div.animate({
    opacity: 0.25,
    width: '256px',
    height: '256px'
}, 3000, function () {
    console.log('動(dòng)畫已結(jié)束');
    // 恢復(fù)至初始狀態(tài):
    $(this).css('opacity', '1.0').css('width', '128px').css('height', '128px');
});
實(shí)際上這個(gè)回調(diào)函數(shù)參數(shù)對(duì)于基本動(dòng)畫也是適用的。
串行動(dòng)畫
jQuery的動(dòng)畫效果還可以串行執(zhí)行,通過delay()方法還可以實(shí)現(xiàn)暫停,這樣,我們可以實(shí)現(xiàn)更復(fù)雜的動(dòng)畫效果,而代碼卻相當(dāng)簡(jiǎn)單:
var div = $('#test-animates');
// 動(dòng)畫效果:slideDown - 暫停 - 放大 - 暫停 - 縮小
div.slideDown(2000)
   .delay(1000)
   .animate({
       width: '256px',
       height: '256px'
   }, 2000)
   .delay(1000)
   .animate({
       width: '128px',
       height: '128px'
   }, 2000);
}
</script>
因?yàn)閯?dòng)畫需要執(zhí)行一段時(shí)間崔拥,所以jQuery必須不斷返回新的Promise對(duì)象才能后續(xù)執(zhí)行操作。簡(jiǎn)單地把動(dòng)畫封裝在函數(shù)中是不夠的讳嘱。
為什么有的動(dòng)畫沒有效果
你可能會(huì)遇到栋烤,有的動(dòng)畫如slideUp()根本沒有效果。這是因?yàn)閖Query動(dòng)畫的原理是逐漸改變CSS的值股淡,如height從100px逐漸變?yōu)?身隐。但是很多不是block性質(zhì)的DOM元素,對(duì)它們?cè)O(shè)置height根本就不起作用唯灵,所以動(dòng)畫也就沒有效果贾铝。
此外,jQuery也沒有實(shí)現(xiàn)對(duì)background-color的動(dòng)畫效果埠帕,用animate()設(shè)置background-color也沒有效果垢揩。這種情況下可以使用CSS3的transition實(shí)現(xiàn)動(dòng)畫效果。
  • 擴(kuò)展

編寫jQuery插件
給jQuery對(duì)象綁定一個(gè)新方法是通過擴(kuò)展$.fn對(duì)象實(shí)現(xiàn)的敛瓷。讓我們來編寫第一個(gè)擴(kuò)展——highlight1():
$.fn.highlight1 = function () {
    // this已綁定為當(dāng)前jQuery對(duì)象:
    this.css('backgroundColor', '#fffceb').css('color', '#d85030');
    return this;
}
注意到函數(shù)內(nèi)部的this在調(diào)用時(shí)被綁定為jQuery對(duì)象叁巨,所以函數(shù)內(nèi)部代碼可以正常調(diào)用所有jQuery對(duì)象的方法。
對(duì)于如下的HTML結(jié)構(gòu):
<!-- HTML結(jié)構(gòu) -->
<div id="test-highlight1">
    <p>什么是<span>jQuery</span></p>
    <p><span>jQuery</span>是目前最流行的<span>JavaScript</span>庫呐籽。</p>
</div>
為什么最后要return this;锋勺?因?yàn)閖Query對(duì)象支持鏈?zhǔn)讲僮魇慈常覀冏约簩懙臄U(kuò)展方法也要能繼續(xù)鏈?zhǔn)较氯ィ?$('span.hl').highlight1().slideDown();
不然,用戶調(diào)用的時(shí)候庶橱,就不得不把上面的代碼拆成兩行贮勃。
但是這個(gè)版本并不完美。有的用戶希望高亮的顏色能自己來指定苏章,怎么辦寂嘉?
我們可以給方法加個(gè)參數(shù),讓用戶自己把參數(shù)用對(duì)象傳進(jìn)去布近。于是我們有了第二個(gè)版本的highlight2():
$.fn.highlight2 = function (options) {
    // 要考慮到各種情況:
    // options為undefined
    // options只有部分key
    var bgcolor = options && options.backgroundColor || '#fffceb';
    var color = options && options.color || '#d85030';
    this.css('backgroundColor', bgcolor).css('color', color);
    return this;
}
對(duì)于默認(rèn)值的處理垫释,我們用了一個(gè)簡(jiǎn)單的&&和||短路操作符,總能得到一個(gè)有效的值撑瞧。
另一種方法是使用jQuery提供的輔助方法$.extend(target, obj1, obj2, ...)棵譬,它把多個(gè)object對(duì)象的屬性合并到第一個(gè)target對(duì)象中,遇到同名屬性预伺,總是使用靠后的對(duì)象的值订咸,也就是越往后優(yōu)先級(jí)越高:
// 把默認(rèn)值和用戶傳入的options合并到對(duì)象{}中并返回:
var opts = $.extend({}, {
    backgroundColor: '#00a8e6',
    color: '#ffffff'
}, options);
緊接著用戶對(duì)highlight2()提出了意見:每次調(diào)用都需要傳入自定義的設(shè)置,能不能讓我自己設(shè)定一個(gè)缺省值酬诀,以后的調(diào)用統(tǒng)一使用無參數(shù)的highlight2()脏嚷?
也就是說,我們?cè)O(shè)定的默認(rèn)值應(yīng)該能允許用戶修改瞒御。
那默認(rèn)值放哪比較合適父叙?放全局變量肯定不合適,最佳地點(diǎn)是$.fn.highlight2這個(gè)函數(shù)對(duì)象本身肴裙。
于是最終版的highlight()終于誕生了:
$.fn.highlight = function (options) {
    // 合并默認(rèn)值和用戶設(shè)定值:
    var opts = $.extend({}, $.fn.highlight.defaults, options);
    this.css('backgroundColor', opts.backgroundColor).css('color', opts.color);
    return this;
}
// 設(shè)定默認(rèn)值:
$.fn.highlight.defaults = {
    color: '#d85030',
    backgroundColor: '#fff8de'
}
這次用戶終于滿意了趾唱。用戶使用時(shí),只需一次性設(shè)定默認(rèn)值:
$.fn.highlight.defaults.color = '#fff';
$.fn.highlight.defaults.backgroundColor = '#000';
然后就可以非常簡(jiǎn)單地調(diào)用highlight()了蜻懦。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末甜癞,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子宛乃,更是在濱河造成了極大的恐慌悠咱,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,755評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件征炼,死亡現(xiàn)場(chǎng)離奇詭異析既,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)谆奥,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門眼坏,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人雄右,你說我怎么就攤上這事空骚》慕玻” “怎么了?”我有些...
    開封第一講書人閱讀 165,138評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵囤屹,是天一觀的道長熬甚。 經(jīng)常有香客問我,道長肋坚,這世上最難降的妖魔是什么乡括? 我笑而不...
    開封第一講書人閱讀 58,791評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮智厌,結(jié)果婚禮上诲泌,老公的妹妹穿的比我還像新娘。我一直安慰自己铣鹏,他們只是感情好敷扫,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著诚卸,像睡著了一般葵第。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上合溺,一...
    開封第一講書人閱讀 51,631評(píng)論 1 305
  • 那天卒密,我揣著相機(jī)與錄音,去河邊找鬼棠赛。 笑死哮奇,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的睛约。 我是一名探鬼主播鼎俘,決...
    沈念sama閱讀 40,362評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼痰腮!你這毒婦竟也來了而芥?” 一聲冷哼從身側(cè)響起律罢,我...
    開封第一講書人閱讀 39,264評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤膀值,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后误辑,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體沧踏,經(jīng)...
    沈念sama閱讀 45,724評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年巾钉,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了翘狱。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,040評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡砰苍,死狀恐怖潦匈,靈堂內(nèi)的尸體忽然破棺而出阱高,到底是詐尸還是另有隱情,我是刑警寧澤茬缩,帶...
    沈念sama閱讀 35,742評(píng)論 5 346
  • 正文 年R本政府宣布赤惊,位于F島的核電站,受9級(jí)特大地震影響凰锡,放射性物質(zhì)發(fā)生泄漏未舟。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評(píng)論 3 330
  • 文/蒙蒙 一掂为、第九天 我趴在偏房一處隱蔽的房頂上張望裕膀。 院中可真熱鬧,春花似錦勇哗、人聲如沸昼扛。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽野揪。三九已至,卻和暖如春瞧栗,著一層夾襖步出監(jiān)牢的瞬間斯稳,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評(píng)論 1 270
  • 我被黑心中介騙來泰國打工迹恐, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留挣惰,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,247評(píng)論 3 371
  • 正文 我出身青樓殴边,卻偏偏與公主長得像憎茂,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子锤岸,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 1.JQuery 基礎(chǔ) 改變web開發(fā)人員創(chuàng)造搞交互性界面的方式竖幔。設(shè)計(jì)者無需花費(fèi)時(shí)間糾纏JS復(fù)雜的高級(jí)特性。 1....
    LaBaby_閱讀 1,174評(píng)論 0 1
  • 1.JQuery 基礎(chǔ) 改變web開發(fā)人員創(chuàng)造搞交互性界面的方式是偷。設(shè)計(jì)者無需花費(fèi)時(shí)間糾纏JS復(fù)雜的高級(jí)特性拳氢。 1....
    LaBaby_閱讀 1,336評(píng)論 0 2
  • (續(xù)jQuery基礎(chǔ)(1)) 第5章 DOM節(jié)點(diǎn)的復(fù)制與替換 (1)DOM拷貝clone() 克隆節(jié)點(diǎn)是DOM的常...
    凜0_0閱讀 1,342評(píng)論 0 8
  • 原文鏈接 http://blog.poetries.top/2016/10/20/review-jQuery 關(guān)注...
    程序員poetry閱讀 16,645評(píng)論 18 503
  • 但過了一年,他要去北京念書蛋铆,可那學(xué)姐不能跟他一起去馋评,他們便分手了。 他去了北京念書刺啦,我也跟著他去了留特,每次在學(xué)校看著...
    月光下的櫻花草閱讀 162評(píng)論 0 0