jQuery學習筆記

寒青發表於2018-05-10

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:hiddenopacity: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. attributesproperties的區別

  • 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是相對於documentposition是相對於父級元素

結構控制

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 請求的方法型別,GETPOST。預設是GET
  • data 要傳送的資料
  • dataType 伺服器返回的資料型別,支援xmlhtmlscriptjsonjsonptext
  • success 請求成功時呼叫的處理函式 success(data, textStatus, jqXHR)
  • context 回撥函式執行時的上下文
  • cache 預設為true,是否為請求單獨新增一個隨機引數以防止瀏覽器快取
  • error 請求錯誤時的呼叫函式。

    • error(jqXHR, textStatus, errorThrown)
    • 第二個引數是表示請求狀態的字串:timeouterrorabortparsererror
    • 第三個引數是當HTTP錯誤發生時,具體的錯誤描述:Not FoundInternal Server Error
  • complete 請求結束(無論成功或失敗)時的一個回撥函式。

    • complete(jqXHR, textStatus)
    • 第二個引數時表示請求狀態的字串:successnotmodifiederrortimeoutabortparsererror
  • 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物件有三個狀態:donefailprocess

- `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/alwaysthen的返回值的區別。從功能上看,它們都可以新增回撥函式,但是,方法的返回值是不同的。前組的返回值是原來的那個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 ,註冊的兩次回撥函式依次被執行後,看到的輸出是:helloinner

這是兩次 defer.done 的結果,第一個回撥函式返回了一個新的 defer 沒任何作用。

如果換成 then 方法:defer.then(function () {...});

它跟兩次 defer.done 是不同的。 new_defer 會在 inner 那裡的 defer 被觸發時再被觸發,所以輸出結果是:innerhello

更一般地來說 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 response12

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() 鎖定呼叫鏈,但是如果開啟了memoryflag,新新增的函式仍然會執行
  • callbacks.has() 檢查一個函式是否處於回撥鏈之中
  • callbacks.fired() 檢查回撥鏈是否被激發
  • callbacks.locked() 檢查回撥鏈是否被鎖定

相關文章