天天看點

提高jQuery的性能

1,從google code加載jQuery

google

code已經集合了幾個JavaScript庫,我們可以從那裡加載這些庫而不必通過自己的伺服器加載。這樣的好處是節省帶寬,如果使用者通路過同樣加載了這些庫的網站後,JavaScript庫會緩存在使用者端,提高加載速度。

<a href="http://www.lzby.net/boho/blog/?p=391#">PLAIN TEXT</a>

JavaScript:

&lt;script

src="http://www.google.com/jsapi"&gt;&lt;/script&gt;

&lt;script type="text/javascript"&gt;&lt;!--

// 加載jQuery

google.load("jquery", "1.2.6");

google.setOnLoadCallback(function() {

    // 自己的代碼...

});

// --&gt;&lt;/script&gt;

也可以直接聲明一個指向:

src="http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js"

type="text/javascript"&gt;&lt;/script&gt;  

2,将比對選擇器元素對象儲存在變量中。

尤其在循環體裡,下面的做法影響運作效率:

for (i = 0; i

&amp;lt;1000; i++) {

var myList = $('.myList');

myList.append('This is list item ' + i);

}

上面的代碼在我的機器上耗時1066毫秒。除非我瘋了才會将選擇器表達示放在循環體裡。應該這樣做:

 myList.append('This is list item

' + i);

上面的代碼耗時隻有224毫秒。想要更快還可以這樣做:

var myListItems = '&lt;ul&gt;';

myListItems+='This is list item ' + i;

myListItems+='&lt;/ul&gt;';

myList.html(myListItems);

也就是說盡量減少直接對DOM進行操作,還有直接填充内容比插入内容要快。上面的代碼隻需185毫秒,盡管不算很明顯,但至少顯示出可優化的空間。

3,如果可以,選擇器盡量選取ID屬性。

4,為選擇器設定一個範圍。

如果使用$('.myDiv')這樣的選擇器表達示,毫無疑問的是對整個DOM進行了一次周遊,然後傳回比對的元素對象。然而如果為它設定一個範圍将會提高運作效率。jQuery(expression,

context)函數有兩個參數,第一個是表達示,第二個就是範圍。指定了範圍參數,選擇器隻會在這個範圍内進行選取。例如:

var selectedItem = $('#listItem' +

i, $('.myList'));

5,正常運用連接配接語句

jQuery最cool的一種用法就是将方法和調用連接配接起來,例如切換某元素的class屬性:

$('myDiv').removeClass('off').addClass('on');

如果要連接配接的方法調用很多,jQuery同樣和JavaScript一樣可以将語句分行書寫:

$('#mypanel')

.find('TABLE

.firstCol')

.removeClass('.firstCol')

.css('background'

: 'red')

.append('&lt;span&gt;This

cell is now red&lt;/span&gt;');

如果養成良好的連接配接語句的習慣,有助于減入選擇器的使用。上面的代碼隻進行了一次選擇器操作,然而卻幹完了4件事。很難想像将它分開進行4次操作會消耗多少資源,而且書寫代碼量也少了很多。是以為什麼不這麼做呢?

接下來再看看,要選取表格中的class='firstColumn'的單元格,并設它的背景色為red:

$('#myTable').find('.firstColumn').css('background','red');

很顯然,上面的代碼進行了兩次選擇器操作。而.css()調用隻會作用到表格中class='firstColumn'的單元格裡。這時我們又需要對同一表格中class='lastColumn'的單元格進行操作該如何做呢?看起來不能将它們連在一起寫,難道要重新寫一句嗎?當然不用:

$('#myTable')

.find('.firstColumn')

.css('background','red')

.end()

.find('.lastColumn')

.css('background','blue');

這裡用到了.end(),作用是如果連接配接了多個選擇器,将傳回到最初的一個選擇器中。也就是将$('#myTable').find('.firstColumn')傳回到$('#myTable'),然後再$('#myTable').find('.lastColumn')。這樣就解決了剛才說的問題。

同樣支援自定義的jQuery函數:

$.fn.makeRed =

function() {

return $(this).css('background',

'red');

$('#myTable').find('.firstColumn').makeRed().append('hello');

6,學會在适當的時候使用動畫

檢視一下jQuery的源代碼會發現jQuery庫中很強大的slideDown()和fadeIn()都是調用jQuery本身的animate()方法:

slideDown:

function(speed,callback){

return this.animate({height: "show"},

speed, callback);

},

fadeIn:

function(speed, callback){

return this.animate({opacity: "show"},

animate()方法采用從一個CSS樣式到另一個CSS樣式的過渡實作動畫效果。是以可以為元素定義背景色、長度、寬度和透明試等等形式的動畫效果。

$('#myList

li').mouseover(function() {

$(this).animate({"height": 100}, "slow");

上面的代碼實作滑鼠移到元素上時,高度漸漸變成100像素。

有别于jQuery其它的函數方法,animate()支援自動隊列。一旦一個動畫完成後又會進行第二個動畫,這并不需要進行回調處理:

$('#myBox').mouseover(function() {

$(this).animate({ "width": 200

}, "slow");

$(this).animate({"height": 200}, "slow");

animate()還支援多個css同時放置。例如:

$(this).animate({ "width": 200,

"height": 200 }, "slow");

7,事件委托

jQuery比以往更重視元素事件委托,這更能展現unobtrusively(無侵入)原則。在元素上添加太多的事件會降低效率,也不便書寫和調試。而事件委托能用較少的代碼完成同樣的功能。

$('#myTable

TD').click(function(){

$(this).css('background',

因為就不需要在DOM内添加onClick事件,進而使DOM很簡潔。假設有一個表格,10列50行,每點選一個單元格後,該單元格背景變red。是不是要進行500次事件委托呢?很明顯是不需要:

$('#myTable').click(function(e) {

var clicked = $(e.target);

clicked.css('background',

'e'傳回實際響應點選的元素,是以可以取得被點選的目标元素。看上去簡潔許多。

8,書寫自己的選擇器

必要的時候,可以建立自己的選擇器。當jQuery内置的選擇器無法更有效地完成選取操作時,自己建立的選擇器可以對内置選擇器進行擴充。

$.extend($.expr[':'], {

over100pixels: function(a) {

return $(a).height()&amp;gt; 100;

$('.box:over100pixels').click(function() {

alert('The element you

clicked is over 100 pixels high');

上面代碼的第一部分是建立一個自定義的選擇器,即傳回所有高度超過100像素的元素。代碼的第二部分隻是将比對的元素進行事件綁定,比對元素被點選時,彈出一個對話框。這裡隻是說明選擇器是可擴充的,我将陸續釋出有關擴充jQuery擴充的post。

9,利用noconflict來重命名jQuery對象

大多數的JavaScript架構庫使用$标記符,如果在同一頁裡使用了不同的JavaScript架構,而且都用$做标記符,必定會引志沖突。好在jQuery提供了noConflict()方法來重命名标記符。例如:

var $j = jQuery.noConflict();

$j('#myDiv').hide();

這時$符号變成了$j。隻要出現$j的标記符就是使用jQuery庫。

10,判斷畫片加載完畢

這個問題好像沒有答案。怎樣去判斷一個圖檔真正加載完畢了呢?用.load()方法吧。

$('#myImage').attr('src', 'image.jpg').load(function() {

alert('Image

Loaded');

運作後如果圖檔加載完畢了,會彈出對話框。這是使用了回調函數。

11,如果檢查DOM中的某元素是否存在

如果要對某元素進行操作,并不需要先去檢查該元素時否存在于DOM中。因為jQuery的方法或函數對那些并不存在的元素根本不會進行任何操作。但如果需要知道是否已有標明或標明的數量時,可以用length屬性:

if ($('#myDiv).length) {

12,簡化的$(document).ready

通常需要這樣寫:

$(document).ready(function (){

// ...

其實還可以這樣寫:

$(function (){

});  

繼續閱讀