jQuery學習筆記
jQuery大部分功能需要根據文件的DOM模型來工作,首先需要正確地解析到整個文件的DOM模型結構。使用jQuery需要在整個文件被瀏覽器完全載入後才開始進行。
$(document).ready(function () {
alert("Hello World!");
$("p").click(function (event) {
alert("Thanks for visiting!");
})
});
$
是在jQuery中使用的變數名,可以使用jQuery.noConflict()
避免衝突,它的返回值就是jQuery物件。
jQuery.noConflict();
$j = jQuery.noConflict();
jQuery物件與DOM物件之間的轉換
使用$()
得到的是一個jQuery物件。它封裝了很多 DOM 物件的操作,但是它和 DOM 物件之間是不同的。只有當obj
是一個DOM物件時才能使用obj.innerHTML
;相應地,如果是jQuery物件應該使用 obj.html()
。
- 從 DOM 物件轉到 jQuery 物件:
$(obj)
- 從 jQuery 物件轉到 DOM 物件:
obj[0]
比較正規地從 jQuery 物件到 DOM 的轉換,是使用 jQuery 物件的 get()
方法:
$(function () {
$("li").get();
$("li").get(0);
$("li").get(-1);
});
jQuery選擇器
1. 常規選擇器
-
$("*")
選擇所有節點 -
$("#id")
ID選擇器,注意其中的一些特殊字元,如.
-
$(".class")
類選擇器 -
$("tag")
標籤選擇器 $("子元素")
$("直接子元素")
-
:focus
獲取焦點元素 -
:first-child/:last-child
選擇第一個/最後一個元素 -
:first/:last
擷取第一個/最後一個符合條件的元素 -
("pre+next")
直接兄弟元素 -
("pre~siblings")
兄弟元素 -
:nth-child()
索引選擇,索引從1開始:nth-child(odd)
:nth-child(even)
:nth-child(4n)
2. 屬性選擇器
-
[name~="value"]
屬性中包括某單詞 -
[name="value"]
屬性完全等於指定值 -
[name!="value"]
屬性不等於指定值 -
[name]
包括有指定屬性的元素
3. 控制元件選擇器
-
:checked
選擇所有被選中的元素 -
:selected
被選擇的元素 -
:disabled/:enabled
選擇被停用/未停用的元素 -
:hidden
隱藏元素,不僅是[type="hidden"]
,還有displa:none
-
:visible
可見控制元件,visibility:hidden
和opacity:0
同樣被認為是可見 -
:input :button :checkbox :file :image :password :radio :reset :submit :text
具體控制元件,影像控制元件是[type="image"]
4. 其他選擇器
-
[name="value"] [name2="value2"]
多個AND條件 -
("selector1, selector2, selectorN")
多個OR條件 -
:not()
否定選擇 -
(':contains("text")')
包含有指定內容的元素 -
:eq() :lt() :gt() :even :odd
列表索引選擇(不支援負數) -
(':has(selector)')
符合條件的再次過濾 -
:header
選擇h1,h2,h3...
標題元素 -
:only-child
僅有一個子元素的元素 -
:empty
空元素,即無內容也無元素 -
:parent
非空元素
節點漫遊
1. 呼叫鏈處理
-
.add()
向已有的節點序列中新增新的物件 -
.andSelf()
在呼叫鏈中,隨時加入原始序列 -
.eq()
指定索引選取節點,支援負數 -
.filter() .is() .not() .find() .first() .last() .has()
序列選擇 -
.end()
節點回溯
$(function () {
$('ul.first').find('.foo').css('background-color', 'red')
.end().find('.bar').css('background-color', 'green');
});
2. 子節點
-
.children()
所有的子節點,可加入過濾條件,.children(selector)
3. 兄弟節點
-
.siblings() .next() .nextAll() .nextUntil() .prevAll() .prevUntil() .closet()
選擇兄弟節點
4. 父節點
-
.parent() .parents() .parentUntil()
父節點選擇
元素控制
1. attributes
和properties
的區別
-
attributes
是XML結構中的屬性節點<div onload="prettyPrint()"></div>
-
properties
是DOM物件,物件屬性$('body').get(0).tagName;
2. 類與屬性控制
-
.addCLass() .hasClass() .removeClass()
新增一個類,判斷是否有指定類,刪除類
$('body').addClass('test');
$('body').addClass(function (index, current) {
return current + 'new';
});
$('body').removeClass('test');
$('body').removeClass(function (index, current) {
return current + ' ' + 'other';
});
-
.toggleClass()
類的開關式轉換
$('img').toggleClass(); //對所有類的開關
$('img').toggleClass('test'); //對指定類的開關
$('img').toggleClass(isTrue); //根據`isTrue`判斷所有類的開關
$('img').toggleClass('test', isTrue); //根據`isTrue`判斷指定類的開關
//同 `$('img').toggleClass('test');` 只是類名由函式返回
$('img').toggleClass(function (index, className, isTrue) {
return 'name'
});
// `isTrue`作為函式的第三個引數傳入
$('img').toggleClass(function (index, className, isTrue) {
return 'name'
}, isTrue);
-
.attr()
獲取或設定一個屬性值
// $("#greatphoto").attr('alt'); //獲取屬性`
$("#greatphoto").attr('alt', 'Shenzhen Brush Seller'); //設定屬性`
// 同時設定多個屬性
$('#greatphoto').attr({
alt: 'Shen Brush Seller',
title: 'photo by Kelly Clark'
});
//設定屬性為函式返回值,函式的上下文為當前元素
$('#greatphoto').attr('title', function (i, val) {
return val + ' - photo by Kelly Clark';
})
-
.prop()
用法同.attr()
,只是物件變成了properties
-
.removeAttr() .removeProp()
刪除屬性 -
.val()
設定或獲取元素的表單值,通常用於表單元素
$('input').val();
$('input').val('other');
-
.html()
設定或獲取元素的節點html
$('div').html();
$('div').html('<div>測試</div>');
$('div').html(function (index, old) {
return old + '<span>另外的內容</span>';
});
3. 樣式控制
-
.css()
獲取或設定指定的CSS樣式
$('body').css('background-color', 'red');
$('body').css('background-color', function (index, value) {
return value + '1';
});
$('body').css({color: 'green', 'background-color': 'red'});
-
.width() .height()
獲取或設定元素的寬和高
$('body').width();
$('body').width(50);
$('body').width(function (index, value) {
return value += 10;
})
-
.innerWidth() .innerHeight() .outerHeight() .outerWidth()
元素的其他尺寸值 -
.scrollLefgt() .scrollTop()
獲取或設定捲軸的位置 -
.offset() .position()
獲取元素的座標-
offset
是相對於document
,position
是相對於父級元素
-
結構控制
1. 文字節點
-
.html() .text()
設定和獲取節點的文字值。設定時.text()
會轉義標籤,獲取時.text()
會移除所有標籤。
2. 子節點
.append() .prepend()
$('.inner').append('<p>Test</p>');
引數可以有多種形式:
var $newdiv1 = $('<div id="object1"/>'),
newdiv2 = document.createElement('div'),
existingdiv1 = document.getElementById('foo');
$('body').append($newdiv1, [newdiv2, existingdiv1]);
3. 兄弟節點
.after() .before()
$('.inner').after('<p>Test</p>');
4. 父節點
.wrap() .wrap() .wrapInner()
$('.inner').wrap('<div class="new"></div>');
$('.inner').wrapAll('<div class="new"></div>');
$('.inner').wrapInner('<div class="new"></div>');
5. 複製/刪除/替換節點
-
.clone()
複製節點,可選參數列示是否處理已繫結的事件與資料-
.clone(true)
處理當前節點的事件與資料 -
.clone(true, true)
處理當前節點及所有子節點的事件與資料
-
-
.detach()
暫時移除節點,之後可以再次恢復指定位置 -
.remove()
永久移除節點 -
.empty()
清除一個節點的所有內部內容 -
.unwrap()
移除節點的父節點
工具函式
-
.map()
遍歷所有成員
$(':checkbox').map(function () {
return this.id;
}).get().join(',');
$(':checkbox').map(function (index, node) {
return node.id;
}).get().join(',');
-
.slice()
序列切片,支援一個或兩個引數,支援負數
$('li').slice(2).css('background-color', 'red');
$('li').slice(2, 4).css('background-color', 'green');
$('li').slice(-2, -1).css('background-color', 'blue');
通用工具
-
$.each() $.map()
遍歷列表,$.map()
可以用於物件
$.each([52, 97], function (index, value) {
console.log((index + ' : ' + value));
});
$.map([0, 1, 2], function (index, n) {
return n + 4;
});
$.map([0, 1, 2], function (n) {
return n > 0 ? n + 1 : null;
});
$.map([0, 1, 2], function (n) {
return [n, n + 1];
});
var dimensions = {width: 10, height: 15, length: 20};
$.map(dimensions, function (value, key) {
return value * 2;
});
var dimensions = {width: 10, height: 15, length: 20};
$.map(dimensions, function (value, key) {
return key;
});
-
$.extend()
合併物件,第一個參數列示是否進行遞迴深入
var object = $.extend({}, object1, object2);
var object = $.extend(true, {}, object1, object2);
-
$.merge()
合併列表
$.merge([0, 1, 2], [2, 3, 4]);
-
.grep()
過濾列表,第三個參數列示是否為取反
$.grep([0, 1, 2], function (array, index) {
return n > 0;
});//[1,2]
$.grep([0, 1, 2], function (array, index) {
return n > 0;
}, true);//[0]
-
$.inArray()
存在判斷
$.inArray(value, array [, fromIndex])
-
$.isArray() $.isEmptyObject() $.isFunction() $.iSNumeric() $.isPainObject() $.isWindow $.isXMLDoc()
型別判斷 -
$.noop()
空函式 -
$.now()
當前時間戳,值為(new Date).getTime()
-
$.parseJson() $.parseXML()
把字串解析為物件
var xml = "<rss version='2.0'><channel><title>RSS Title</title></channel></rss>",
xmlDoc = $.parseXML(xml),
$xml = $(xmlDoc),
$title = $xml.find("title");
-
$.trim()
去頭去尾$.trim(str)
-
$.type()
判斷引數的型別 -
$.unique()
遍歷後去重。$.unique(arraty)
上下文繫結
-
$.proxy()
為函式繫結上下文$.proxy(function,context)
$.proxy(context,name)
var o = {
x: '123',
f: function () {
console.log(this.x)
},
};
var go = function (f) {
f()
};
o.f();// 123
go(o.f);// undefined
go($.proxy(o.f, o));//123
$.proxy(o, 'f')(); //123
當一個函式被傳遞之後,它就失去了原先的上下文。
把資料存到節點中
jQuery提供了一種機制,可以把節點作為資料儲存的容器。
-
$.data()
往節點中獲取/設定資料 -
$.removeData()
刪除資料
在內部實現上,jQuery會在指定節點新增一個內部標識,以此為key
,把資料存在內部閉包的一個結構中。
事實上,jQuery的事件繫結機制也使用了這套資料介面。
$.data($('#data').get(0), 'test', '123');
$('#data').data('test', '456');
事件處理
1. 事件繫結
在 jQuery1.7之後,推薦統一使用on()
來進行事件繫結。
-
.on()
繫結事件on()
的基本使用方式是:.on(event,handler)
-
.off()
移除事件 -
.one()
繫結單次事件
$('#btn').on('click', function (eventObj) {
console.log('Hello');
})
對於handler
,它預設的上下文是觸發事件的節點:
$('#btn').on('click', function (eventObj) {
console.log(this);
})
使用$.proxy()
可以隨意控制上下文:
$('#btn').on('click',
$.proxy(function (eventObj) {
console.log(this.a);
}, {a: 123})); // 123
event
引數還支援透過:
- 以`.`分割的子名字
- 以空格分割的多個事件
$('#btn').on('click.my', (function (eventObj) {
console.log('123');
}
)
);
var f = function () {
$('#btn').off('click.my')
};
多個事件:
$('#btn').on('click.my click.other',
(function (eventObj) {
console.log('123');
}
)
);
var f = function () {
$('#btn').off('click.my')
}
on()
的另一種呼叫形式:
$('#btn').on({
'click': function (eventObj) {
console.log('click');
},
'mousemove': function (eventObj) {
console.log('move');
}
});
off()
的使用方式與on()
完全類似:
var f = function (eventObj) {
console.log('Hello');
};
$('#btn').on('click', f);
$('#btn').off('click');
2. 事件觸發
事件的觸發有兩種方式,一是使用預定的“事件函式”(.click()
,.focus()
),二是使用trigger()
或triggerHandler()
。
$('#btn').on('click', function (eventObj) {
console.log("hello");
});
$('#btn').click();
$('#btn').trigger('click');
trigger()
與triggerHandler()
不同之處在於前面是觸發事件,而後者是執行繫結函式。
$('#btn').on('focus', function (event) {
console.log("Hello");
});
$('#btn').triggerHandler('focus');
trigger()
和triggerHandler()
也用於觸發自定義事件。
$('#btn').on('my', function (event) {
console.log("Hello");
});
$('#btn').triggerHandler('my');
trigger()
和triggerHandler()
觸發事件時,可以帶上引數:
$('#btn').on('my', function (event) {
console.log(obj);
});
$('#btn').trigger('my', {a: 123});
3. 事件型別
行為事件:
-
.click()
單擊 -
.dbclick()
雙擊 -
.blur()
失去焦點時 -
.change()
值變化時 -
.focus()
獲取焦點時 -
.focusin()
jQuery擴充套件的獲取焦點 -
.focusout()
jQuery擴充套件的失去焦點 -
.resize()
調整大小 -
.scroll()
滾動 -
.select()
被選擇 -
.submit()
表單被提交
鍵盤事件:
-
.keydown()
按下鍵 -
.keyup()
放開鍵
滑鼠事件:
-
.mousedown()
點下滑鼠 -
.mouseup()
鬆開滑鼠 -
.mouseover()
游標移入 -
.mouseout()
游標移出 -
.mousemove()
游標在其上移動 -
.mouseleave() .mouseenter()
游標移出/移入
頁面事件:
-
.ready()
準備就緒 -
.unload()
離開當前頁時,針對window
物件 -
.error()
發生錯誤時 -
.load()
正在載入
4. 事件物件
-
event.currentTarget,event,target
事件繫結節點/事件的觸發節點(冒泡行為) -
event.delegateTarget
繫結事件的物件,通常就是event.currentTarget
-
event.relatedTarget
相關的節點,主要用於一些轉換式的事件。比如滑鼠移入,表示它從哪個節點來的 -
event.which
標明哪個按鈕觸發了事件,滑鼠和鍵盤的鍵標識統一在這個屬性中 -
event.preventDefault() event.isDefaultPrevented()
禁止預設行為 -
event.stopImmediateProgation() event.isImmediateProgationStopped()
不僅禁止冒泡。還終止繫結函式鏈的繼續進行 -
event.stopPropagation(),event.isPropagationStopped()
禁止冒泡 -
event.pageX,event.pageY
事件觸發時相對於document
的滑鼠位置 -
event.namespace
事件觸發時的名字空間,比如trigger('click.namespace')
-
event.data
額外傳入的資料 -
event.result
上一個繫結函式的返回值 -
event.timeStamp
事件觸發時的時間,其值為(new Date).getTime()
-
event.type
事件型別
如果一個繫結函式最後返回了false
,則預設是event.preventDefault()
和event.stopPropagation()
行為。
AJAX
1. 請求與回撥
jQuery的AJAX,核心的請求處理函式只有一個,就是$.ajax()
,然後就是一個簡單的上層函式。
$.ajax()
的基本使用形式是:
jQuey.ajax(settings)
settings
是一個物件,裡面包含了所有的配置項。
-
url
請求的地址。 -
type
請求的方法型別,GET
,POST
。預設是GET
。 -
data
要傳送的資料 -
dataType
伺服器返回的資料型別,支援xml
,html
,script
,json
,jsonp
,text
-
success
請求成功時呼叫的處理函式success(data, textStatus, jqXHR)
-
context
回撥函式執行時的上下文 -
cache
預設為true
,是否為請求單獨新增一個隨機引數以防止瀏覽器快取 -
error
請求錯誤時的呼叫函式。error(jqXHR, textStatus, errorThrown)
- 第二個引數是表示請求狀態的字串:
timeout
,error
,abort
,parsererror
- 第三個引數是當HTTP錯誤發生時,具體的錯誤描述:
Not Found
,Internal Server Error
等
-
complete
請求結束(無論成功或失敗)時的一個回撥函式。complete(jqXHR, textStatus)
- 第二個引數時表示請求狀態的字串:
success
,notmodified
,error
,timeout
,abort
,parsererror
。
-
jsonp
一個引數名,預設是callback
,一般用於指明回撥函式名。設定成false
可以讓請求沒有callback
引數。 -
jsonpCallback
callback
引數值。預設是自動生成的一個隨機值。
2. 請求的狀態
對於全域性的所有AJAX請求而言,可以在任意節點上繫結到全域性任意AJAX請求的每一個事件:
$('#loading').ajaxStart(function () {
$(this).show();
});
-
.ajaxStart()
請求將要發出時 -
.ajaxSend()
請求將要發出時(在.ajaxStart()
後) -
.ajaxSuccess()
請求成功 -
.ajaxError()
請求錯誤 -
.ajaxComplete()
請求完成 -
.ajaxStop()
請求結束(在.ajaxComplete()
後)
3. 工具函式
-
.serialize()
解析表單引數項,返回字串
$('form').submit(function () {
alert($(this).serialize());
return false;
});
-
.serializeArray()
解析表單引數項,返回一個列表物件。
$('form').submit(function () {
alert($(this).serializeArray());
return false;
});
泛化回撥
1. Deferred
-
Deferred
物件是在jQuery1.5中引入的回撥管理物件。其作用是把一堆函式按順序放入一個呼叫鏈,然後根據狀態來依次呼叫這些函式。AJAX的所有操作都是使用它來進行封裝的。
var obj = $.Deferred(function (a) {
});
obj.done(function () {
console.log("1");
});
obj.done(function () {
console.log("2");
});
obj.resolve();
總的來說:jQuery的Deferred
物件有三個狀態:done
,fail
,process
。
- `process` 只能先於其他兩個狀態先被激發。
- `done`和`fail`互斥,只能激發一個。
- `process`可以被重複激發,而`done`和`fail`只能激發一次。
然後,jQuery提供了一些函式用於新增回撥,激發狀態等。
-
deferred.done()
新增一個或多個成功回撥 -
deferred.fail()
新增一個或多個失敗回撥 -
deferred.always()
新增一個函式,同時應用於成功和失敗 -
deferred.progress()
新增一個函式用於準備回撥 -
deferred.then()
依次接受三個函式,分別用於成功,失敗,準備狀態 -
deferred.reject()
激發失敗狀態 -
deferred.resolve()
激發成功狀態 -
deferred.notify()
激發準備狀態
如果一個Deferred
已經被激發,則新新增的對應的函式會被立即執行。
jQuery還提供了一個jQuery.when()
的回撥管理函式,可以用於方便地管理多個事件併發的情況。
var defer = $.ajax({
url: 'test.html',
dataType: 'json'
});
defer.done(function (data) {
console.log(data);
});
done()
做的事和使用success()
定義是一樣的。
當我們需要完成,像“請求A和請求B都完成時,執行函式”之類的需求時,使用$.when()
就可以了。
var defer_1 = $.ajax({
url: 'json.html',
dataType: 'json'
});
var defer_2 = $.ajax({
url: 'jsonp.html',
dataType: 'jsonp'
});
var new_defer = $.when(defer_1, defer_2);
new_defer.done(function () {
console.log("hello");
});
在$.when()
中的Deferred
,只要有一個是fail
,則整體結果為fail
。
Deferred
的回撥函式的執行順序與它們的新增順序一致。
這裡特別注意一點,就是done/fail/always
與then
的返回值的區別。從功能上看,它們都可以新增回撥函式,但是,方法的返回值是不同的。前組的返回值是原來的那個defer
物件,而then
返回的是一個新的defer
物件。
then
返回新的defer
這種形式,可以用於方便地實現非同步函式的鏈式呼叫。
defer.done(function () {
return $.ajax({
url: '/json',
dataType: 'json',
success: function () {
console.log("inner");
}
})
}).done(function () {
console.log("hello");
});
等同於是呼叫了兩次 defer.done
, defer.done
,註冊的兩次回撥函式依次被執行後,看到的輸出是:hello
,inner
。
這是兩次 defer.done
的結果,第一個回撥函式返回了一個新的 defer
沒任何作用。
如果換成 then
方法:defer.then(function () {...});
它跟兩次 defer.done
是不同的。 new_defer
會在 inner
那裡的 defer
被觸發時再被觸發,所以輸出結果是:inner
,hello
。
更一般地來說 then
的行為,就是前面的註冊函式的返回值,會作為後面註冊函式的引數值:
var defer = $.ajax({
url: '/json',
dataType: 'json'
});
defer.then(function (res) {
console.log(res);
return 1;
}).then(function (res) {
console.log(res);
return 2;
}).then(function (res) {
console.log(res);
});
上面程式碼的輸入結果是:ajax response
,1
,2
。
2. Callbacks
事實上,Deferred
機制,只是在Callbacks
機制的上層進行了一層簡單封裝。Callbacks
物件才是真正的jQuery中定義的原始的回撥管理機制。
var obj = $.Callbacks();
obj.add(function () {
console.log("1");
});
obj.add(function () {
console.log("2");
});
obj.fire();
Callbacks
物件的初始化支援一組控制引數:
-
$.Callbacks(flags)
初始化一個回撥管理物件。flags
是空格分割的多個字串,以定義此回撥物件的行為:-
once
回撥鏈只能被激發一次 -
memory
回撥鏈被激發後,新新增的函式被立即執行 -
unique
相同的回撥函式只能被新增一次 -
stopOnFalse
當有回撥函式返回false
時終止呼叫鏈的執行
-
CallbackS
的控制方法:
-
callbacks.add()
新增一個或一串回撥函式 -
callbacks.fire()
激發回撥 -
callbacks.remove()
從呼叫鏈中移除指定的函式 -
callbacks.empty()
清空呼叫鏈 -
callbacks.disable()
關閉呼叫鏈的繼續執行,新新增的函式也不會被執行 -
callbacks.lock()
鎖定呼叫鏈,但是如果開啟了memory
的flag
,新新增的函式仍然會執行 -
callbacks.has()
檢查一個函式是否處於回撥鏈之中 -
callbacks.fired()
檢查回撥鏈是否被激發 -
callbacks.locked()
檢查回撥鏈是否被鎖定