知己知彼,面進阿里 ——不屈小強
整理了這些作為下階段讀源碼前的知識儲備,同時分享給大家。共勉。
總述
jQuery 框架提供了很多方法,但大致上可以分為3 大類:
- 獲取jQuery 對象的方法
- 在jQuery 對象間跳轉的方法
- 獲取jQuery 對象后調用的方法
獲取 jQuery 對象
是怎樣獲取jQuery 對象。大致來說,是通過最核心的$()
方法,將頁面上的元素(或者在頁面上不存在的 html 片段)包裝成 jQuery 對象。$()方法
里面支持的語法又包括:
- 分別是表達式(包括類表達式.,id 表達式#,元素表達式等)
- 符號(包括后代符號space,next 符號+等)
- 過濾器(包括:過濾器和[]過濾器)
- 現在顯然還有更多
通過以上組合,通過選擇器 $()
可”查詢“得到 jQuery 對象(或者jQuery 對象的集合)。
對象跳轉
是在jQuery 對象間的跳轉。也就是說,已經得到了一個jQuery 對象,但並不是想要的,那么可以通過一系列的跳轉方法,比如parent()、next()、children()、find()等,或者過濾篩選的方法,比如eq、filter()、not()等,來得到最終想要操作的jQuery 對象。
用跳轉和過濾方式得到的jQuery 結果,往往通過比較復雜的表達式組合,可以達到同樣的目的。
比如說 $("div").eq(3)
,也可以用$("div:eq(3)")
達到同樣的目的。
又比如說$("div").find("span")
,可以用$("div span")
取到同樣的元素。
方法是很靈活的,要根據具體的情況來選擇。根據經驗來說,HTML 頁面寫得越規范,使用 jQuery 就越簡單。
還有一種情況,在得到了jQuery()對象之后,想要判斷其是否滿足條件,那么可以調用 is()、hasClass()等方法,返回一個boolean 值,進行后續的判斷。這類方法也可以歸到這類。
方法調用
在獲取准確的 jQuery 對象之后,調用其上的各種方法,來進行操作。這一步反而是比較簡單的了。
后面就是對 jQuery 框架各種方法的簡要介紹。
常用API
$(…);
/** * 一切的核心,可以跟4 種參數。 */
$();
/** * 返回jQuery 對象或者jQuery 對象的集合 * 比如$("#id")、$(".class") */
$(expression);
/** * 返回jQuery 對象,或者jQuery 對象的集合 * 比如$("<span>hello world</span>") */
$(html)
/** * 返回jQuery 對象,或者jQuery 對象的集合 * 比如$(document.body) */
$(element)
/** * 所有元素 */
$(*)
jQuery 對象獲取
/** * 返回該jQuery 對象在集合中的索引 */
jQuery.index(element);
/** * 遍歷jQuery 對象集合,在每個對象上執行 callback 函數, * function callback(index, domElement){ * this //DOMElement * }; */
jQuery.each(function); /** * 返回 jQuery 對象集合的大小 */ jQuery.size(); /** * 相當於size()方法 */ jQuery.length /** * 獲取原生 DomElement 對象的 Array, * 即將 jQuery 對象轉成 數組對象, * 雖然 jQuery 對象也有 length 屬性,且可用下標讀寫 * 但並非是數組對象。 */ jQuery.get() /** * 獲取原生 DomElement 對象 */ jQuery.get(index) /** * 獲取 jQuery 對象集合中的一個 jQuery 對象 */ jQuery.eq(position)
Data 相關方法
在匹配的元素身上存值(store data), .data()
方法允許在我們以一種安全的方式附加數據到 dom 元素,不會產生循環引用和內存泄露。
jQuery.data(name) // 取值
jQuery.data(name, value) // 賦值
jQuery.removeData(name) // 清理
$( "body" ).data( "foo", 52 );
$( "body" ).data( "bar", { myType: "test", count: 40 } );
$( "body" ).data( { baz: [ 1, 2, 3 ] } );
$( "body" ).data( "foo" ); // 52
$( "body" ).data(); // { foo: 52, bar: { myType: "test", count: 40 }, baz: [ 1, 2, 3 ] }
選擇器
/** * 多目標選擇器 * 可以選擇多個元素或者表達式, * 包裝成 jQuery 對象的集合 * 例子:$("div,span") */
$("table tr td"); //multiple(selector1, selector2)
$("#id > span"); //直接節點
$("label + input") //next(prev, next) 同級的緊挨着的下一個
$("#prev ~ div") // siblings(prev, siblings),同樣要求是同級
基本的過濾器
$(":header"); // 所有 header, <h1>~<h6>
$("tr:odd"); // 選中所有奇數行
$("tr:even"); // 選中所有偶數行
$(":animated"); // 選中所有當前有特效的素
$("div:animated");// 選中運行動畫的
$("tr:first"); // 選中第一行
$("tr:last"); // 選中最后一行
$("input:not(:checked)"); //選中所有沒有“checked”
$("td:gt(4)"); // 選中所有index 是4 之后的td
$("td:lt(4)"); // 選中所有index 是4 之前的td
$("td:eq(4)"); // 選中index 是 4 的td
$("td").eq(4); // 選中index 是 4 的td
內容過濾選擇器
$("div:contains('John')"); // 選中所有包含"John"的div
$("td:empty"); // 選中所有內容為空的td
$("div:has(p)"); // 選中包含有<p>元素的<div>元素,返回jQuery 對象集合
$("td:parent"); //選中所有包含子節點的元素,包括文本也可以算是子節點
可見性過濾器
$("span:hidden"); // 選中所有隱藏的<span>
$("span:visible"); // 選中所有可見的<span>
關於可見性,這里需要額外說明的。在老版本的 jQuery 中 visibility:hidden;
是認為不可見的,我有證據,
Sizzle.selectors.filters.hidden = function(elem){
return "hidden" === elem.type ||
jQuery.css(elem, "display") === "none" ||
jQuery.css(elem, "visibility") === "hidden";
};
這段代碼出自 jquery-1.3.1.js
,然而到近代的版本中(在1.3.2就改了)
jQuery.expr.filters.hidden = function( elem ) {
var width = elem.offsetWidth,
height = elem.offsetHeight;
// 沒有 visibility 什么事
return ( width === 0 && height === 0 ) || (!jQuery.support.reliableHiddenOffsets && ((elem.style && elem.style.display) || jQuery.css( elem, "display" )) === "none");
};
簡單的說就是:如果元素占用空間了,就認為是可見的。只要不是0的都算可見的。
所以,visibility:hidden;
或者 opacity:0;
由於占有空間,它們算事“可見”的。
屬性過濾器
$("div[id]"); // 選中包含 id 屬性的div
$("input[name$='bc']"); // 選中 name 屬性以 'bc' 結尾的 input
$("input[name^='letter']"); // 選中屬性 name 是以'letter'開頭的 input
$("input[tag*='man']"); // 屬性tag里包含'man'
$("input[abc='def']"); // 屬性 abc 的值為 'def'
$("input[title!='722']"); // 選中屬性 title 不包含'722'的
$("input[id][gender$='man']"); // 選中包含id 屬性,和以'man'結尾的屬性 gender 的<input>元素
孩子過濾器
$("ul li:nth-child(2)"); // 選中自身是<ul>元素的第二個子節點的<li>元素,注意這個計算是從 1 開始的,不是從0 開始
$("div span:firstChild"); // 選中自身是<div>元素的第一個子節點的<span>元素
$("div span:lastChild"); // 選中自身是<div>元素的最后一個子節點的<span>元素
表單過濾器
$(":button"); //所有 <button> 和 <input type="button"> 元素
$("form :checkbox"); // 選中所有<form>標簽下的<input type="checkbox"> 不過這樣會比較慢
$("input:checkbox"); // 推薦
$(":file"); // 選中所有<input type="file">
$(":hidden"); // 選中所有隱藏元素,以及<input type="hidden">
$(":input"); // 選中所有<input>
$(":text"); // 選中所有<input type="text">
$(":password"); // 選中所有<input type="password">
$(":radio"); // 選中所有<input type="radio">
$("input:radio"); // 最佳實踐是這樣
$(":image"); // 選中所有<input type="image">
$(":reset"); // 選中所有<input type="reset">
$(":submit"); // 選中所有<input type="submit">
$("input:enabled"); // 選中所有enabled 的<input>元素
$("input:disabled"); // 選中所有disabled 的<input>元素
$("input:checked"); // 選中所有 checked 的 checkbox
$("input:selected"); // 選中所有 selected 的<option>元素
屬性相關的方法
jQuery.removeAttr(name);
jQuery.attr(name); // 返回屬性的值,比如$("img").attr("src")
jQuery.attr(key,value); // 這是設置屬性的值
jQuery.attr(properties); // 也是設置屬性的值
$("img").attr({
src: "/images/hat.gif",
title: "jQuery",
alt: "jQuery Logo"
});
jQuery.attr(key,function); // function 計算出的結果,賦給key // 在回調函數中 function callback(index) {
// index == position in the jQuery object
// this means DOM Element
}
類相關的操作
jQuery.toggleClass(class); // 反復加減 class
jQuery.toggleClass(class,switch); // 增加一個 switch 表達式
// 表達式計算后返回 class 名稱
$( "div.foo" ).toggleClass(function() {
if ( $( this ).parent().is( ".bar" ) ) {
return "happy";
} else {
return "sad";
}
});
jQuery.hasClass(class); // 返回boolean
jQuery.removeClass(class); // 去掉掛載的 class
jQueyr.addClass(class); // 加載 class
html相關的操作
jQuery.html(); // 返回包含的html 文本
jQuery.html(val); // 用val 替換包含的 html 文本,輸入的代碼會被執行
文本相關的方法
jQuery.text(); // 返回包含的純文本,不會包括html 標簽,比如<span>abcd</span>,調用 .text() 方法,只會返回abcd,不會返回<span>abcd</span>
jQuery.text(val); // 用 val 替換包含的純文本,和html(val)方法的區別在於,所有的內容會被看作是純文本,不會作為html 標簽進行處理,比如調用.text("<span>abcd</span>"),<span> 和 </span>不會被認為是html 標簽,而是作為純文本顯示了。
值相關的操作
jQuery.val(); // 返回 string 或者array
jQuery.val(val); // 設置 string 值
jQuery.val(array); // 設置多個值,以上 3 個方法,主要都是用在表單標簽里,如<input type="text">,<input type="checkbox">等
在jQuery 對象之間查找
需要弄清: 文本和節點是兩回事,在 DOM 里就分開了。
jQuery.parent(expr); // 找父親節點,可以傳入expr 進行過濾,比如
$("span").parent();
$("span").parent(". class"); // 用表達式過濾
jQuery.parents(expr); // 祖先元素,不限於父元素
jQuery.children(expr); // 返回所有子節點(不包括文本),和 parents()方法不一樣的是,這個方法只會返回直接的孩子節點,不會返回所有的子孫節點
jQuery.contents(); // 返回下面的所有內容,包括節點和文本。這個方法和 children()的區別就在於,包括空白文本,也會被作為一個jQuery 對象返回,children()則只會返回節點
jQuery.prev(); // 返回上一個兄弟節點,不是所有的兄弟節點
jQuery.prevAll(); // 返回所有之前的兄弟節點
jQuery.next(); // 返回下一個兄弟節點,不是所有的兄弟節點 (+)
jQuery.nextAll(); // 返回所有之后的兄弟節點(~)
jQuery.siblings(); // 返回兄弟姐妹節點,不分前后
jQuery.add(expr); // 往既有的jQuery 對象集合中增加新的jQuery 對象,例子:
$("div").add("p");
jQuery.find(expr); // 從當前的初始集合下去找,不會返回初始集合內容:
$("body").find("div");
// 等同於:
jQuery.find("body div");
jQuery.filter(expr); // 從初始的jQuery 對象集合中篩選出一部分
串聯方法
jQuery.andSelf(); // 把最后一次查詢前一次的集合,也增加到最終結果集中,比如:
$("div").find("p").andSelf(); 這樣結果集中包括所有的<p>和<div>。如果是$("div").find("p"),那就只有<p>,沒有<div>
jQuery.end(); // 把最后一次查詢前一次的集合,作為最終結果集,比如
$("p").find("span").end(); // 所有的<p>,沒有<span>
DOM 文檔操作方法
a.append(b); // b 加到 a 上
$("div").append("<span>hello</span>");
a.appendTo(b); // a 加到 b 上
$("<span>hello</span>").appendTo("#div");
$("span").appendTo("div"); //隱藏的 move,移動元素
/* 比如在: <div id='a'>a: <span> hello </span> </div> <div id='b'>b: </div> 經過 $('span').appendTo("#b"); 結果會是正樣: a: b: hello */
jQuery.prepend(content); // 在選擇元素的內部第一個位置插入
a.prependTo(b); // a 插到 b 內部的排頭位置
jQuery.after(content); 注意是 content,在外部插入,插入到后面,比如
$("#foo").after("<span>hello</span>"); // 參數是內容,不能是選擇器
jQuery.insertAfter(selector);// 允許是選擇器
$("<span>hello</span>").insertAfter("#foo");
jQuery.before(content); // 在外部插入,插入到前面, 參數不是選擇器
jQuery.insertBefore(selector); // 外面插入
jQuery.wrapInner(html); // 在內部插入標簽,比如
$("p").wrapInner("<span></span>");
jQuery.wrap(html); // 在外部插入標簽,比如
$("p").wrap("<div></div>"); // 所有的 p 都會被各自的div 包裹
jQuery.wrapAll(html); // 所選元素會被同一個大的 html 整個的全部包裹
jQuery.replaceWith(content); 比如
$(this).replaceWith("<div>"+$(this).text()+"</div>");
jQuery.replaceAll(selector);
$("<div>hello</div>").replaceAll("p");
jQuery.empty();
$("p").empty(); // 從娃娃做起,會把<p>下面的所有子節點清空,但不清理 p
jQuery.remove(expr);
$("p").remove(); // 從自身做起,會把所有<p>移除,可以用表達式做參數,進行過濾
// 表面看跟 remove 做的一樣,刪除元素;
// 但是保留了元素中的數據或事件, 通過返回值返回,留存后用,
// 需要時候隨時能補上去,綁定的數據事件不受影響。
jQuery.detach();
jQuery.clone([withDataAndEvents ] ));
/* * 使用案例 在適用 append 的時候,隱約的我們發現了它具有移動的功效: <div class="container"> <div class="hello">Hello</div> <div class="goodbye">Goodbye</div> </div> $( ".hello" ).appendTo( ".goodbye" ); 結果變成了這樣: <div class="container"> <div class="goodbye"> Goodbye <div class="hello">Hello</div> </div> </div> 如果我們的需求是額外的拷貝一份元素到目的地: $( ".hello" ).clone().appendTo( ".goodbye" ); 這樣會更方便,結果會是這樣: <div class="container"> <div class="hello">Hello</div> <div class="goodbye"> Goodbye <div class="hello">Hello</div> </div> </div> clone 的用法也分兩種: clone(true); // 克隆,並且連帶數據和綁定的事件 clone()/clone(false); // 克隆,表面結構 */
CSS 相關方法
jQuery.css(name); // 獲取一個 css 屬性的值,比如
$("p").css("color")
jQuery.css(object); // 設置css 屬性的值,比如
$("p").css({
"color":"red",
"border":"1px red solid"
});
jQuery.css(name,value);
$("p").css("color","red");
位置計算相關方法
jQuery.scrollLeft(); // 設置滾動條偏移,這個方法對可見元素或不可見元素都生效
jQuery.scrollTop(); // 設置滾動條偏移,這個方法對可見元素或不可見元素都生效
jQuery.offset(); // 計算偏移量,返回值有 2 個屬性,分別是 top 和left
jQuery.position(); // 計算位置,返回值也有2 個屬性,top 和 left,返回:
[object Object] {
left: 34.546875,
top: 11
}
這里需要額外補充:
The .offset() method allows us to retrieve the current position of an element relative to the document. Contrast this with .position(), which retrieves the current position relative to the offset parent.
簡單來說就是:offset 是相對於 document,而 position 相對於父元素。
寬度和高度計算相關方法
這組方法需要結合CSS 的盒子模型來理解,margin 始終不參與計算
jQuery.height(); // 計算的是 content
jQuery.innerHeight(); // 計算的是 content+padding
jQuery.outerHeight(); // 計算的是content+padding+border
jQuery.width();
jQuery.innerWidth();
jQuery.outerWidth();
瀏覽器及特性檢測
$.support,可以檢測當前瀏覽器是否支持下列屬性,返回boolean。包括boxModel、cssFloat、
opacity、tbody 等
$.browser,檢測當前瀏覽器類型,返回一個map,其中可能的值有safari、opera、msie、mozilla
數據緩存方法
// 該類方法是jQuery.data()方法和jQuery.removeData()的另一種形式,增加的elem 參數是DOM Element
$.data(elem, name);// 取出elem 上name 的值
$.data(elem, name, value); // 設置elem,name為 value
$.removeData(elem, name); //刪除 elem 上的 name
$.removeData(elem); // 刪除elem 上的所有緩存數據
工具方法
$.isArray(obj); // 檢測一個對象是否是數組
$.isFunction(obj); // 檢測一個對象是否是函數
$.trim(str); // 去除string 的空格
$.( value, array [, fromIndex ] )
$.inArray(value, array); // 返回value 在array 中的下標, 如果沒有找到則返回-1
$.inArray(123, ["john",1,123,"f"]); // return2
$.unique(array); // 去除array 中的重復元素,該方法只對DOM Element 有效,對string 和 number 無效
總結
最后,由於篇幅限制,把最重要的 事件綁定
和 ajax
獨立出來,並且也還沒寫完呢,先到這里。