2010-03-19 51 views
16

我遇到了使用多個jQuery綁定幾千個元素和輸入的加載速度問題,有沒有更高效的方法來做到這一點?jQuery綁定效率

該網站能夠通過ajax調用在產品列表之間切換,頁面無法刷新。有些清單有10個項目,大約有100個,大約有2000多個。當我開始在清單之間翻轉時,速度問題就出現了。每次加載2000+項目列表時,系統拖動約10秒鐘。

在重建列表之前,我將目標元素的html設置爲'',並解除綁定下面的兩個綁定。我確信它與我在回調中所做的所有父母,下一個和子女電話有關。任何幫助深表感謝。

環路2500倍

<ul> 
    <li><input type="text" class="product-code" /></li> 
    <li>PROD-CODE</li> 
    ... 
    <li>PRICE</li> 
</ul> 

末環

$('li.product-code').bind('click', function(event){ 

    selector = '#p-'+ $(this).prev('li').children('input').attr('lm'); 

     $(selector).val(

      ($(selector).val() == '' ? 1 : (parseFloat($(selector).val()) + 1)) 

     ); 

    Remote.Cart.lastProduct = selector; 
    Remote.Cart.Products.Push( 

      Remote.Cart.customerKey, 
      { 
       code  : $(this).prev('li').children('input').attr('code'), 
       title  : $(this).next('li').html(), 
       quantity : $('#p-'+ $(this).prev('li').children('input').attr('lm')).val(), 
       price  : $(this).prev('li').children('input').attr('price'), 
       weight : $(this).prev('li').children('input').attr('weight'), 
       taxable : $(this).prev('li').children('input').attr('taxable'), 
       productId : $(this).prev('li').children('input').attr('productId'), 
       links  : $(this).prev('li').children('input').attr('productLinks') 
      }, 
      '#p-'+ $(this).prev('li').children('input').attr('lm'), 
      false, 
      (parseFloat($(selector).val()) - 1) 

    ); 

    return false; 

}); 

$('input.product-qty').bind('keyup', function(){ 

    Remote.Cart.lastProduct = '#p-'+ $(this).attr('lm'); 
    Remote.Cart.Products.Push( 

      Remote.Cart.customerKey, 
      { 
       code  : $(this).attr('code') , 
       title  : $(this).parent().next('li').next('li').html(), 
       quantity : $(this).val(), 
       price  : $(this).attr('price'), 
       weight : $(this).attr('weight'), 
       taxable : $(this).attr('taxable'), 
       productId : $(this).attr('productId'), 
       links  : $(this).attr('productLinks') 
      }, 
      '#p-'+ $(this).attr('lm'), 
      false, 
      previousValue 
    ); 
}); 

回答

28

你要綁定一個處理的2500倍,而不是讓你的函數使用活的或委託像這樣:

$('li.product-code').live('click', function(event){ 
$('input.product-qty').live('keyup', function(){ 

.live()偵聽點擊冒泡的DOM級別再與上下文中執行事件的點擊來源。這意味着你有一個事件處理程序,而不是他們的2500,這意味着它是很多在瀏覽器上更快,更容易。

如果你有一個包裹沒有被替換(仍然在所有的Ajax調用)被替換內容的容器,你可以把它更多的地方像這樣:

$('#container').delegate('li.product-code', 'click', function(event){ 
$('#container').delegate('input.product-qty', 'keyup', function(){ 

這樣做的結果是事件被捕之前泡泡次數較少。

另一個痛點是可能創建的元素,你可以發佈代碼?通常很容易的優化會在那裏產生很大的性能提升。

更新

在jQuery 1.7的,所述方法.live()不推薦使用。使用.on()附加事件處理程序。舊版本的jQuery的用戶應優先使用.delegate().live() - JQuery Docs

+0

現場是贏家!現在我唯一的速度掛斷是我下載的一個非右鍵單擊插件。如果沒有綁定,創建列表是瞬間的,現在是約半秒。隨着無右鍵單擊腳本掛起,但這是由於我想象的綁定。非常感謝! – clownshoes 2010-03-19 20:34:27

+0

@chelfers - 你正在使用哪個沒有右鍵點擊的插件?這應該也很容易切換到'.live()'並且立即獲得所有的代碼......如果你沒有在這裏做過這個回覆,我會去看看。 – 2010-05-24 00:52:41

+0

'委託()'是絕對要走的路。當您想要捕捉哪些事件的數千個元素時,它比替代方案更加優化。唯一需要注意的是它需要jQuery 1.4。 – 2010-08-24 12:56:22

0

你應該看看jqridflexigrid財產以後,讓你做分頁這就是配發的數據輸出的一次,因此最好限制你一次投出多少錢,即使這些事情適合你的項目,你也必須弄清楚如何限制數據是底線

+0

問題是我需要根據客戶要求在一個頁面上的所有數據。我已經構建了一個分頁系統,但未使用-_- – clownshoes 2010-03-19 20:39:33

2

將您的點擊事件綁定到整個文檔,並在該功能中,查看event.target以查看實際點擊了哪個產品元素。這樣你只需要做一次綁定。

+0

更好的辦法可能不是將其綁定到整個文檔,而是綁定到父ul或ol元素。我絕對會避免與現場一起,因爲這也有性能問題,在這種情況下完全可以避免。 – Jan 2012-02-13 15:02:27

0

首先,使用Firebug內置的分析器來檢查大部分延遲是在哪裏;只需點擊「個人資料」,運行您的慢動作,再次點擊並查看哪些通話費用最高。

二看「直播」事件處理:http://api.jquery.com/live/

這種工作方式是,有隻有一個事件處理程序,望着整個文檔,委託給生活事件處理程序。當你有很多元素時,這會更快,因爲你不需要爲每個元素特別添加一個事件處理器。

+0

我去了現場處理。分析器沒有太多幫助,因爲它讓我瞭解了我已經知道的讓腳本陷入困境的一般意義。 – clownshoes 2010-03-19 20:38:33