jQuery 1.4 小閱兵
為了歡度jQuery四歲生日(jQuery由John Resig 於 2006/01/14 在 BarCamp NYC 首次發表[註]),jQuery開發團隊在2010/01/14釋出了jQuery 1.4版。
簡單整理一下我所理解的1.4改版重點:
- 大量重構常用的函數,降低程式複雜度(主要是減少內部函數彼此呼叫的次數),達到改善效能的目標。
- *.css(), .attr(), .val(), .html(), .text(), .append(), .prepend(), .before(), .after(), .replaceWith(), .wrap(), .wrapInner(), .offset(), .addClass(), .removeClass(), .toggleClass() 可傳入函數,由函數的傳回值當作參數值。(傳入函數當成參數的做法,有個術語叫Function Settter)
- *.css(), .attr(), .val(), .html(), .text(), .append(), .prepend(), .offset(), .addClass(), .removeClass(), .toggleClass() 在Function Setter時,該函數的第二個參數即原值。這點很方便,例如,如果要在所有的<a>顯示文字的後方加上"[L]"字串,過去會寫成:
$("a”).each(function(i) { var $a = $(this); $a.html($a.html() + "[L]"); });
現在可以結合2, 3點的新功能,寫成:
$("a”).html(function(i, html) { return html + “[L]”; });
變簡單很多吧!
- $.ajax在傳送陣列參數時,預設會改用ary[]=elem1&ary[]=elem2的Query String表示法(過去會轉成ary=elem1&ary=elem2),這多半跟PHP、Ruby on Rails搭配使用。 如果想要保留原做法
,需另外設定jQuery.ajaxSettings.traditional = true;
。
- *$.ajax可不指定dataType,由Response的ContentType決定: applcation/json時自動調為"json",text/javascript或application/x=javascript時變成”script”,text/xml時視為"xml”。
- $.ajax設定ifModified:true時,支援ETag檢查決定是否使用Cache的內容。
- *JSON解析原本都是用eval,從1.4起會在Browser有支援的情況下使用內建的JSON Parser(如: IE8, FF3.1, Chrome, Safari),比eval來得安全也更有效率。
- .serialize支援HTML5的欄位元素,例如: datetime, range。
- *$.ajax多了context參數,在Callback函數中可以透過this直接存取context所傳入的元素物件,不必再用Closure,簡單很多! 例如:
$.ajax({
url: “gettime.aspx”,
context: $(“#spnNowTime”),
success: function(s) { context.html(s); }
});
- $.get, $.post, $getJSON, $.getScript 的success Callback多了第三個傳入參數--XHR。以前若想存取XHR,就必須放棄$.get等簡易寫法,回頭改用$.ajax。
- 送出AJAX Request時不管有無資料內容,一律傳送Content-Type Header,以符合某些應用場合的要求。
- 可以指定JSONP的callback函數名稱了! 也就是在邊做邊學jQuery第14集中提到的jsonp1238089172708,現在可透過jsonpCallback參數自訂。
- $.ajax用onreadystatechange取代setTimeout輪詢,改善效能 。
- .text()支援CDATA
- *很酷的新HTML元素建構寫法:
jQuery("<div/>", {
id: "foo",
css: {
height: "50px",
width: "50px",
color: "blue",
backgroundColor: "#ccc"
},
click: function() {
$(this).css("backgroundColor", "red");
}
}).appendTo("body");
- *.eq(-N), .get(-N)可以取"倒數第N個",.first(), .last()可以取第一個跟最後一個。
- 過去jQuery()會傳回document的jQuery物件,1.4版起則改為傳回空的jQuery集合,以便動態加入元素。jQuery().ready()在1.4仍維持jQuery(document).ready()的效果,但建議不要再用了。
- jQuery(“tagName”)改用getElementByTagName,速度大幅改善;$("<div>”), $(“<div />”), $(“<div></div>”)均改用document.createElement,$(“<div></div>”)效能己改善。
- .css()加快兩倍、.addClass(), removeClass(), .hasClass()加快三倍。
- .toggleClass()支援一次切換多個class,例如: toggleClass("class1 class2")。
- *.data(myCacheObject)可以用傳入的物件置換掉整個Cache物件,而.data()可以取回整個Cache物件。
- .data()使用的Cache物件改成有用到才建立,以改善效能。
- 呈現動畫時,可針對不同屬性設定不同的Easing效果。[參考: 天才少年James Padolsey的Demo]
- jQuery.proxy()可以為現有函數產生一個分身,並指定該分身的Scope(簡單來就是強制指定this)。這有什麼用呢? 常見的案例是在事件函數中,要用另一個元素當作this。例如:
var f = function() { alert(this.id); };
$("#A,#B").click(jQuery.proxy(f, $("#A")[0]));
在A,B上掛了同一個click事件,但透過jQuery.proxy指定Scope為A,則B的click事件裡,this也會指向A。
- .bind()時可傳入物件{ click: function() { … }, keydown: function() { … } },一次指定多個事件。
- *克服了change(), submit()在IE裡跟其他瀏覽器部分行為有差異的問題。
- *新事件focusin, focusout。類似focus及blur,但是支援Bubble Up。應用範例,<p>中包了<input>,當<input>取得焦點時,<p>的focusin事件也會被觸發。
- *除了ready, focus(可用focusin取代), blur(可用focusout取代),所有的事件都可以.live()了,萬歲!!! 另外,live的對象也可以指定Context了。(這應該可以克服上回在滲透式live管不到Iframe document的問題)
- .ready()會使用setTimeout持續檢查document.body是否存在,原則上只用來解決Safari瀏覽器的少數問題案例。
- 非IE瀏覽器不再做unload事件的Memory Leak檢查以加快速度。
- .append(), .prepend(), .before(), .after()變快約一倍,.html()變快三倍,.remove(), .empty()變快4倍。
- 新方法: .detach(),將元素自DOM移除,但保留事件函數,多半用在暫時移除,稍後加回去的情境。
- 新方法: .unwrap(),剝掉外層,留下html()的部分。例如: <div id="X"><span>A</span></div>,$("#X").unwrap() -> <span>A</span>
- 內部函數domManip加入Cache機制,jQuery("<div>"), .after("<div>")會比以前快。
- 沒有加進DOM的物件也可以用.before(), .after(), .replaceWith()。例如: jQuery("<div/>").before("<p>Hello</p>").appendTo("body") 。
- *.clone(true)現在連.data()也一併會複製 。
- .offset()支援設定功能,可用來改變元素位置。(設定時,CSS position會被自動改成relative)
- *queue()不再只侷限在動畫應用上,新增.delay(n)函數,可暫停n ms、.next()可跳到下一個動作、clearQueue()可以清除動作。
- *.index()取得元素在同層元素中的排行,.index(selector)取得元素在同層元素同符合selector的排行。
- .has()。$("div”).has(“a”) 相當於 $("div:has(a)”)
- .nextUntil(), .prevUntil(), parentsUntil(),類似.nextAll(), .prevAll(), .parents(),但會一直向後/前/上蒐集元素,直到符合selector元素為止。
- .add(), .closest()支援傳入第二個參數作為Context 。
- jQuery.isEmptyObject()用來判別是否物件沒有任何屬性 。
- jQuery.isPlainObject()用來判別是否為物件 。
- jQuery.contains(A, B)用來判別元素B是否被包在元素A中 。
- *jQuery.noop(),什麼事都不做的空函數,用在一定要傳入函數作為參數的場合。
- jQuery.unique(),只保留DOM元素陣列中不重複的部分,並依在DOM出現順序排列。
- 其他: jQuery.browser支援Engine導向,例如: jQuery.browser.webkit用來判別所有以WebKit開發的Browser、對Java Applet的支援更好、不再使用arguments.callee(ECMAScript 5要廢掉)、使用Closure Compiler而非YUI Min來壓縮jquery-1.4.min.js 。
【改版後不相容之處】
改用1.4,請注意以下的寫法可能會出問題:
- .add()的結果改成依元素在DOM裡的順序排列
- .clone(true)會一併複製事件跟.data()儲存的資料
- jQuery.data(elem)不再只傳回id字串,而是該元素的.data() Cache物件
- jQuery() != jQuery(document)
- *.val(“…”)作用在<option>或<input type=”checkbox”>時,只認value,不再看text
- *jQuery.browser.version現在傳回Engine版本
- 將會阻擋格式不符規定的JSON表示字串
- *預設會以PHP/Rails的ary[]=elem1&ary[]=elem2方法序列化參數,如想維持ary=elem1&ary=elem2的做法,請設定jQuery.ajaxSettings.traditional = true;
- 內建屬性jQuery.className移除
- jQuery.extend(true, …)將不再適用於非物件及陣列
- *$.ajax未指定dataType,而Response.ContentType == “text/javascript”時,將會自動被當成Script執行,不再當成string處理
- $.ajax的ifModified會一併納入ETags決定是否使用Cache。
好消息是,如果你發現原來的js換了1.4有以上問題,懶得改程式又很想用1.4,只要加掛一個Plug-In就可以解決。
<script src="http://code.jquery.com/jquery.js"></script>
<script src="http://code.jquery.com/jquery.compat-1.3.js"></script>
我只能說,jQuery真是佛心來著呀!!
【註】紅色*是我個人認為值得關注的改變