1. 從Google Code加載jQuery
Google Code上已經託管了多種JavaScript類庫,從Google Code上加載jQuery比直接從你的服務器加載更有優點。它節省了你服務器上的帶寬,可以很快的從Google的內容分佈網絡(CDN)上加載JS類庫。更重要的是,若是用戶訪問那些發佈在Google Code上的站點後它會被緩存下來。
這樣作頗有意義。有多少站點使用了沒有被緩存的相同jQuery副本,而這些很容易作到,引入:javascript
<script type="text/javascript" src=" http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script>css
2. 使用備忘單
不只僅是jQuery,不少編程語言也有相似的備忘單,在一張A4的紙上就能夠很容易看到每一個函數的用法。幸運的是已經有好心的傢伙把jQuery的備忘單作得很完善了:
http://www.gscottolson.com/weblog/2008/01/11/jquery-cheat-sheet/
http://colorcharge.com/jquery/html
3. 整合全部的腳本並縮減它們
不錯,這是JavaScript的一個常見技巧。但是一個使用了jQuery的大項目可能使用了不少相關的jQuery插件(本站就使用了easing,localScroll,lightbox,preload),所以它一般是適用的。瀏覽器不能同時加載JS腳本(大多數狀況下),這意味着若是你同一時間加載不少腳本的話,將減緩頁面的加載速度。所以,若是每一個頁面都要加載這些腳本,你應該考慮在發佈以前將這些腳本整合成一個稍大的JS腳本。一些jQuery插件已經最小化了,可是你應該打包你的JS腳本和那些沒有縮減過的腳本,這僅須要幾秒的時間就能夠完成。
就我的而言,我推薦Packer by Dean Edwardsjava
4. 使用Firebug出色的控制檯日誌工具
若是你尚未安裝Firebug,那麼你真的應該把它裝上。除了許多其它有用的特性(好比容許你檢查http傳輸狀況、發現你的CSS問題),它也有極好的日誌命令,容許你很容易調試JS腳本。
這裏有Firebug全部特性的詳細說明。
我最喜歡的特性有」console.info「,經過它你能夠把信息和變量值輸出到控制檯上,而沒必要使用alert;」console.time」則容許你在一組代碼上設置定時器,從而計算出JS腳本運行所花費的時間。這一切都很容易作到:
jquery
console.time('create list');
for (i = 0; i < 1000; i++) {
var myList = $('.myList');
myList.append('This is list item ' + i);
}
console.timeEnd('create list');
5. 經過緩存最小化選擇操做
jQuery的選擇器棒極了。它們能夠在頁面上以極其簡單的方法找到任何元素,可是在內部它們必須經過大量的步驟才能夠實現選擇操做,若是你錯誤的使用它們,那麼你可能發現一切都變得至關慢。
若是你一次又一次的選擇相同元素(例如在一個循環中),那麼你能夠一次選擇出它並放入內存中,同時你能夠在覈心內容裏操做它。看下面的例子,這裏咱們利用循環往UL裏添加條目:
for (i = 0; i < 1000; i++) {
var myList = $('.myList');
myList.append('This is list item ' + i);
}
這在個人PC上Firefox 3花費了1066毫秒時間(能夠設想一下在IE6中的狀況!),對JavaScript而言這個操做至關慢。如今讓咱們來看看下面的代碼,這裏咱們僅使用了一次選擇操做:
var myList = $('.myList');
for (i = 0; i < 1000; i++) {
myList.append('This is list item ' + i);
}
僅僅用了224毫秒,經過移動一行代碼就快了將近4倍。
6. 最小化DOM操做
咱們經過減小對DOM的插入操做可讓上面的代碼運行得更快。DOM的插入操做(像.append(),.prepend(),.after(),.wrap())是至關耗時的,執行這些操做會拖慢程序的運行。
咱們所要作的就是使用字符串拼接來構造一個list項並用一個函數往列表裏添加這些項,好比.html()。請看下面的例子:
程序員
var myList = $('#myList');
for (i=0; i<1000; i++){
myList.append('This is list item ' + i);
}
在個人PC上花費了216毫秒,僅僅在1/5秒左右。可是若是咱們使用字符串構造list項,使用下面的HTML方法完成插入操做:
var myList = $('.myList');
var myListItems = '';
for (i = 0; i < 1000; i++) {
myListItems += '<li>This is list item ' + i + '</li>';
}
myList.html(myListItems);
它耗時185毫秒,儘管沒有快不少,可是也提升了31毫秒的時間。
7. 處理DOM插入操做時,將須要的內容包裝在一個元素中
嗯,不要問我爲何要這樣作(我相信一個有至關經驗的程序員會給你解釋)。
在上面的例子中咱們使用.html()將1000個item項插入到UL中。若是在插入操做以前咱們將這些項包裝在UL標籤中,而後把完整的UL插入到另外一個DIV標籤中,那麼咱們實際上僅僅插入一個標籤而不是1000個,這看起來要更高效些。請看下面這個例子:
var myList = $('.myList');
var myListItems = '<ul>';
for (i = 0; i < 1000; i++) {
myListItems += '<li>This is list item ' + i + '</li>';
}
myListItems += '</ul>';
myList.html(myListItems);
如今所花費的時間僅19毫秒,比咱們以前的第一個例子明顯提升了50倍。
8. 儘量使用ID而不是class
jQuery利用classes進行DOM元素選擇操做與經過ID進行選擇同樣容易,所以與以前相比更自由的使用classes進行元素選擇操做頗有吸引力。不過因爲jQuery使用瀏覽器固有的方法(getElementById )進行選擇操做,所以利用ID進行選擇操做更有優點。有多快呢?讓咱們來看看。
我使用前一個例子,修改它以便於咱們建立的每一個LI有一個惟一的class。而後我將遍歷之,每次選擇一個元素:
// Create our list
var myList = $('.myList');
var myListItems = '<ul>';
for (i = 0; i < 1000; i++) {
myListItems += '<li class="listItem' + i + '">This is a list item</li>';
}
myListItems += '</ul>';
myList.html(myListItems);
// Select each item once
for (i = 0; i < 1000; i++) {
var selectedItem = $('.listItem' + i);
}
正如所想的,個人瀏覽器花費了5066毫秒的時間(5秒多)。所以我修改上述代碼以使用ID而不是class,而後經過ID進行選擇。
// Create our list
var myList = $('.myList');
var myListItems = '<ul>';
for (i = 0; i < 1000; i++) {
myListItems += '<li id="listItem' + i + '">This is a list item</li>';
}
myListItems += '</ul>';
myList.html(myListItems);
// Select each item once
for (i = 0; i < 1000; i++) {
var selectedItem = $('#listItem' + i);
}
僅僅耗時61毫秒,幾乎快了100倍
9. 給選擇器提供上下文
默認狀況下,當你使用相似$('.myDiv')的選擇器時將在整個DOM文檔查找元素,這有很大的代價。
當執行選擇操做時,jQuery函數能夠指定第二個參數:jQuery( expression, context )經過給選擇器提供一個上下文,那就會在這個context中進行元素查找,而沒必要在整個DOM文檔中查找元素。
爲了解釋這個,咱們採用前面的第一段代碼。它建立一個有1000項內容的UL,每項都有一個單獨的class。
而後遍歷之每次選擇一項。你應該記得經過class選擇全部的1000項item須要耗時5秒多。
web
var selectedItem = $('#listItem' + i);
而後我給其添加一個上下文,以便於僅在UL中執行選擇操做:
var selectedItem = $('#listItem' + i, $('.myList'));
因爲效率太差,仍耗時3818毫秒的時間,可是經過一個很小的修改仍得到了25%的速度提高。
10. 正確使用方法鏈
jQuery最炫的一個特性就是jQuery可以連續的進行方法調用。舉例來講,你想去切換元素的class:
$('myDiv').removeClass('off').addClass('on');
若是你像我這樣,你可能在前五分鐘的jQuery學習就能夠更進一步使用它。首先它仍能夠跨行操做(jQuery是JavaScript) ,這意味着你可以寫出下面這樣工整的代碼:
$('#mypanel')
.find('TABLE .firstCol')
.removeClass('.firstCol')
.css('background' : 'red')
.append('<span>This cell is now red</span>');
使用鏈表的習慣將有助於你減小選擇器的使用。然而能夠更深刻使用之,你想在一個元素上執行好幾個函數,可是以某種方式改變了操做的元素:
$('#myTable').find('.firstColumn').css('background','red');
咱們選擇了一個表格,在其中找到class爲」firstColumn」的單元格,而後使之背景變爲紅色。
如今咱們但願將全部class爲」lastColumn」的單元格背景設爲藍色。由於咱們已經使用了find()函數過濾出class不爲」firstColumn」的全部單元格,所以咱們須要再一次對錶格使用選擇操做,咱們難道不能連續進行方法調用嗎?幸運的是jQuery提供了end()函數,這將匹配的元素列表變爲前一次狀態以便於你能夠執行方法鏈表:
$('#myTable')
.find('.firstColumn')
.css('background','red')
.end()
.find('.lastColumn')
.css('background','blue');
寫一個可以進行方法鏈式調用的自定義jQuery函數也很容易。你所作的就是要寫個能修改元素並返回元素的函數。
$.fn.makeRed = function() {
return $(this).css('background', 'red');
}
$('#myTable').find('.firstColumn').makeRed().append('hello');
它很簡單吧!
11. 學會正確使用效果
在我剛開始使用jQuery的時候,就很喜歡這一點:它能夠很容易使用預約義好的各類動畫效果,像slideDown()和fadeIn()之類的。因爲jQuery提供的animate()方法十分易用和強大,咱們很容易深刻使用它。事實上,在jQuery源代碼中很多方法就是經過animate()函數來實現效果的。
ajax
slideDown: function(speed,callback){
return this.animate({height: "show"}, speed, callback);
},
fadeIn: function(speed, callback){
return this.animate({opacity: "show"}, speed, callback);
}
animate()方法僅僅做用在CSS上,根據數值平滑的進行轉換。所以你可以改變寬度、高度、透明度、背景色、top、left、margin、顏色、字體大小以及任何你想要的。
給菜單項添加高度變化的效果是很容易作到的:
$('#myList li').mouseover(function() {
$(this).animate({"height": 100}, "slow");
});
不像其餘的jQuery函數,動畫效果自動的排進隊列,所以若是在第一個特效完成以後你想運行第二個特效,須要兩次調用animate方法:
$('#myBox').mouseover(function() {
$(this).animate({ "width": 200 }, "slow");
$(this).animate({"height": 200}, "slow");
});
若是你想動畫效果同時發生,那麼須要將全部的styles做爲一個參數對象傳入方法中:
$('#myBox').mouseover(function() {
$(this).animate({ "width": 200, "height": 200 }, "slow");
});
你可以給值是數字的屬性添加動畫效果。你也能夠下載插件幫助你給非數字值的屬性添加動畫效果,像
colors and background colors
12. 瞭解事件代理
與以前相比,jQuery可以更容易得向DOM元素無縫添加事件。這是很棒的特性,然而向元素添加太多的事件是效率不好的。在不少狀況下事件代理容許你用少許的事件實現一樣的目的。最好的解釋方法就是使用實例:
express
$('#myTable TD').click(function(){
$(this).css('background', 'red');
});
當咱們點擊表格中的單元格時,上面的代碼將使全部單元格背景變爲紅色。比方說,你有一個10列、50行的網格,那麼就會綁定上500個事件。嗯,這時就是事件代理出場的時候了:
$('#myTable').click(function(e) {
var clicked = $(e.target);
clicked.css('background', 'red');
});
e'包含了事件的信息,包括了實際接收到click事件的目標元素。咱們所要作的就是檢查是哪一個單元格被點擊了。至關的巧妙!
事件代理帶來了另一個好處。正常狀況下,在你往一個元素集合綁定一個事件,該事件僅僅只是綁定到這些集合元素上。若是你向DOM中添加了新的元素,儘管這些新元素被選擇器所匹配,可是這些新元素並不會綁定上事件處理(你贊成個人觀點嗎?),所以不會有事件發生。
當使用事件代理時,你可以在事件被DOM綁定後仍然能夠添加多個被匹配的元素到其中,而它們一樣可以正常工做。
13. 利用classes存儲狀態
這是在html中存儲信息最基本的方法。jQuery擅長基於classes進行元素的操做,所以若是你須要存儲元素的狀態信息,爲何不試試使用額外的class來存儲它呢?
這裏有一個例子。咱們想建立一個展開的菜單。當你點擊按鈕時,咱們但願經過slideDown()和slideUp()進行菜單的展開與收縮。請看下面的HTML:
<div class="menuItem expanded">
<div class="button">
click me
</div>
<div class="panel">
<ul>
<li>Menu item 1</li>
<li>Menu item 2</li>
<li>Menu item 3</li>
</ul>
</div>
</div>
很是的簡單!咱們僅僅向包裝器DIV添加一個額外的class,它只是告訴咱們item項的狀態。所以在按鈕點擊以後咱們所須要的只是click事件處理,這會執行相應的slideUp()和slideDown()方法。
$('.button').click(function() {
var menuItem = $(this).parent();
var panel = menuItem.find('.panel');
if (menuItem.hasClass("expanded")) {
menuItem.removeClass('expanded').addClass('collapsed');
panel.slideUp();
}
else if (menuItem.hasClass("collapsed")) {
menuItem.removeClass('collapsed').addClass('expanded');
panel.slideDown();
}
});
這是很簡單的一個例子,不過你能夠給一個元素或HTML片段添加額外的classes以存儲全部種類的信息。
然而,除了在簡單的狀況以外咱們更應該使用下面這個技巧。
14. 更好的方法是利用jQuery內置的data()方法存儲狀態
因爲某些緣由,這方面沒有很好的文檔能夠參考。jQuery提供了內置的data()方法,與DOM元素不一樣的是,它能夠用來存儲key/value類型的數據。數據的存儲是很容易的:
複製代碼代碼以下:
$('#myDiv').data('currentState', 'off');
咱們修改上一個例子的代碼,以便於咱們可使用相同的HTML內容(除了沒有」expanded」類)並使用data()函數來進行狀態的存儲:
$('.button').click(function() {
var menuItem = $(this).parent();
var panel = menuItem.find('.panel');
if (menuItem.data('collapsed')) {
menuItem.data('collapsed', false);
panel.slideDown();
}
else {
menuItem.data('collapsed', true);
panel.slideUp();
}
});
我相信你也會贊同這種方法的使用的確更加的精巧,對於data()和removeData()的更多信息,請查看
jQuery internals
15. 寫你本身的選擇器
jQuery有許多內置的選擇器用以經過ID、class、標籤、屬性以及其餘元素進行選擇操做。然而當你須要基於其它一些內容進行元素選擇而jQuery卻沒有提供該選擇器時,你能作什麼呢?
嗯,一個解決方案多是從一開始就給元素添加上classes,從而利用這些classes進行元素的選擇操做。然而這被證實很難對jQuery擴展出新的選擇器。
最好的解釋方法就是使用實例:
$.extend($.expr[':'], {
over100pixels: function(a) {
return $(a).height() > 100;
}
});
$('.box:over100pixels').click(function() {
alert('The element you clicked is over 100 pixels high');
});
代碼的前一部分建立一個自定義的選擇器,它能夠找出全部長度超過100px的元素。接下來的代碼僅僅是將click事件綁定到使用該選擇器查找出來的那些元素上。
這裏我不作更具體的講解,可是你能設想一下它有多麼的強大!若是你在google上搜索」custom jquery selector」,你會看到有不少這方面的例子。
16. 精簡你的HTML並在頁面加載後修改它
這個標題可能沒有多大意思,可是這個技巧可能理順你的代碼、減少代碼體積和頁面的下載時間、有助優化你的搜索引擎。請看下面的例子:
編程
<div class="fieldOuter">
<div class="inner">
<div class="field">This is field number 1</div>
</div>
<div class="errorBar">
<div class="icon"><img src="icon.png" alt="icon" /></div>
<div class="message"><span>This is an error message</span></div>
</div>
</div>
<div class="fieldOuter">
<div class="inner">
<div class="field">This is field number 2</div>
</div>
<div class="errorBar">
<div class="icon"><img src="icon.png" alt="icon" /></div>
<div class="message"><span>This is an error message</span></div>
</div>
</div>
上面是一個HTML的具體例子,爲了解釋目的作了少許修改。我相信你也會認爲這段代碼至關的醜陋。若是相似代碼很長的話,你最終會造成一個至關長且醜陋的頁面。所以你能夠像下面這樣處理它:
<div class="field">This is field 1</div>
<div class="field">This is field 2</div>
<div class="field">This is field 3</div>
<div class="field">This is field 4</div>
<div class="field">This is field 5</div>
全部你要作的就是在頁面加載完成以後經過jQuery的操做將醜陋的HTML添加回去:
$(document).ready(function() {
$('.field').before('<div class="fieldOuter"><div class="inner">');
$('.field').after('</div><div class="errorBar"><div class="icon">
<img src="icon.png" alt="icon" /></div><div class="message">
<span>This is an error message</span></div></div></div>');
});
這樣作並不老是可取的,在頁面加載後的一瞬間你將會看到頁面的閃動,可是在特定狀況下你有不少重複的HTML內容,這時經過這個方法你能夠顯著的減少頁面代碼體積,減小無關且重複的標記能使你的SEO從中受益。
17. 爲了速度和SEO方面的考慮,延遲加載內容
另外還有一個方法能夠提高頁面加載速度,理順Spiders搜索的HTML內容,經過在頁面加載以後使用AJAX請求晚加載其餘內容,這樣用戶就能夠立刻開始瀏覽,讓Spider看到你想要它們進行索引的內容。
咱們已經在本身的網站上使用了這個技術。本頁面上部的紫色按鈕會彈出三個表格,方位與Google地圖,這會使咱們頁面大小增長兩倍。所以咱們僅須要把這些HTML內容放入一個靜態頁面中,在頁面加載完成以後經過load()函數加載它:
$('#forms').load('content/headerForms.html', function() {
// Code here runs once the content has loaded
// Put all your event handlers etc. here.
});
我不會在頁面上隨處使用這個技巧。對此,你必須權衡考慮。你須要有額外的頁面請求,並且頁面上的部份內容不能當即呈現給用戶,可是正確的使用這個技巧對優化會頗有幫助。
18. 使用jQuery提供的工具函數
jQuery不只僅有閃光的效果。jQuery做者也提供了一些至關實用的方法,這填補了JacaScript的一些缺陷。
http://docs.jquery.com/Utilities
尤爲,提供一些常見的數組函數的瀏覽器支持是一個補丁。jQuery提供了迭代、過濾、克隆、合併和從數組中去除重複項的方法。
其餘經常使用的函數包括獲得下拉框中的選擇項。用傳統的JavaScript方法,你就必須使用getElementById獲得<select>元素,而後經過遍歷它的子元素找出被選中的元素。而jQuery提供了至關容易使用的方法:
$('#selectList').val();
花時間瀏覽官方網站上的jQuery文檔與一些不經常使用的方法上是很值得的。
19. 使用noConflict重命名jQuery對象
大多數JavaScript框架都使用$符號做爲縮寫,當在同一個頁面使用多個JS框架時,頁面很容易發生衝突。幸運的是有一個簡單的方法。noConflict()函數交回$的控制權並容許你設置成本身的變量名:
$('#selectList').val();
20. 如何得知圖片已加載完畢
這也一個沒有很好文檔說明的問題(至少在我查找時沒看到),可是在建立照片庫、旋轉燈籠效果等方面,它是至關常見的需求。而這在jQuery中很容易實現。
全部你要作的就是在IMG上使用.load()方法,在其中添加一個回調函數。下面的例子改變了一個圖片src的屬性同事附加上一個簡單的load函數:
$('#myImage').attr('src', 'image.jpg').load(function() {
alert('Image Loaded');
});
你應該能夠發現一旦圖片加載完畢就會彈出一個alert。
21. 老是使用最新版本
jQuery仍在不斷的更新,它的做者John Resig一直在尋找提升jQuery性能的方法。jQuery當前的版本是1.3.2,John已經宣稱他正在寫一個新的選擇器引擎Sizzle,這可能會顯著的提升選擇器性能(在Firefox中提高了4倍),所以咱們應當保持最新版本。
22. 如何檢查元素是否存在
你沒必要檢查元素是否在頁面上存在就可使用它,由於若是沒有在DOM中找到合適的元素,jQuery什麼也不會作。但是當咱們須要檢查元素是否被選擇了,或是有多少項被選擇了,你可使用length屬性:
if ($('#myDiv).length) {
// your code
}
簡單之極。
23. 給你的HTML屬性增長JS類
我是從Karl Swedberg那學到這個技巧,過去學習jQuery時一直在看他的書。
他最近在我之前的文章留下了對該用法的評論,基本原則以下示之。
首先,在jQuery加載以後你可使用方法將」JS」類添加到HTML標籤中:
$('HTML').addClass('JS');
由於這僅僅發生在javascript有效的時候,若是用戶打開JavaScript開關,那麼你可使用它給元素添加上CSS風格:
.JS #myDiv{display:none;}
所以,這意味着在JavaScript打開時咱們能夠隱藏內容,而後在須要時使用jQuery顯示這些內容(好比在用戶點擊時收縮或展開內容),同時在關閉JavaScript(以及搜索Spiders)時會看到全部內容。我將在晚些時候使用這個技巧。
能夠在這裏看到
他的全部文章
。
24. 返回'false'以防止默認行爲
這是很明顯的,也可能不是。若是你有這樣的習慣:
複製代碼代碼以下:
<a href="#" class="popup">Click me!</a>
而後添加上以下的事件處理:
$('popup').click(function(){
// Launch popup code
});
你在長頁面使用上述方法時,它可能能夠正常工做。有些時候你會注意到在點擊連接後錨點會跳轉到頁面上部。
全部你要作的就是阻止它的默認行爲,或者實際上你能夠把」return false;」添加到任何事件的默認行爲上。像這樣:
複製代碼代碼以下:
$('popup').click(function(){
// Launch popup code
return false;
});
25. ready事件的簡寫
一個小技巧可是經過使用$(document).ready()的簡寫,你能夠少輸入幾個字符。
取代:
代碼以下:
$(document).ready(function (){
// your code
});
你能夠簡寫成:
$(function (){ // your code });