簡體   English   中英

綁定父元素與元素直接相比有優缺點嗎?

[英]Are there advantages or disadvantages to binding on a parent element versus the element directly?

為了更好地理解jQuery性能,我遇到了以下問題。 考慮將click事件綁定到列表中的項目的兩個大致相同的解決方案:

清單項目:

<div id="items">
    <div class="item"><a href="#">One</a></div>
    <div class="item"><a href="#">Two</a></div>
    <div class="item"><a href="#">Three</a></div>
</div>

<div id="items2">
    <div class="item"><a href="#">One</a></div>
    <div class="item"><a href="#">Two</a></div>
    <div class="item"><a href="#">Three</a></div>
</div>

請注意,有兩個完整列表(除了ID)。 現在,考慮以下jQuery來綁定item s中每個錨點的客戶端事件:

$('#items').on('click', '.item a', function(e) {
   console.log("### Items click"); 
});

$('#items2 .item a').on('click', function(e) {
    console.log("### Items2 click");
});

這實現了相同的結果,因為單擊列表中的項目將輸出它們各自的消息。

觀察綁定的事件,在第一種情況下,click事件被綁定到#items容器,沒有事件綁定到子#items 但是,在第二種情況下, 沒有將 click事件綁定到父#items2 ,但每個子元素都有一個click事件。

現在,我的問題是: 一個明顯優於另一個嗎? 天真,我會認為第一種情況更可取,但缺乏對jQuery內部的了解,很可能這兩者在引擎蓋下是相同的。

我准備了一個小提琴來演示這兩個案例。 觀察jQuery為元素構建的事件,我得出了上述假設(您可以在Web瀏覽器的控制台中看到輸出)。

除非你正在處理大量的元素,否則兩種方式都無關緊要。 問題是你何時需要提高效率:在綁定時或觸發時?

免責聲明:我並不認為任何這些測試都是完美的。 另外,我只在Chrome中測試過。

約束時間

我不知道答案,所以我決定嘗試測試一切。 首先,我假設使用委托會更快地進行綁定(它只需綁定一次而不是X次)。 這似乎是正確的。

http://jsperf.com/on-delegate-vs-not-bind-only

不委托:慢100%

觸發時間

接下來,我認為不使用委托可能實際上更快地觸發事件,因為不需要DOM移動來檢查事件觸發。 無論出於何種原因,我對此不正確:

http://jsperf.com/on-delegate-vs-not-trigger-pls

不委托:慢60%

(最初的.trigger是為了防止jQuery緩存委托事件,我相信它.trigger 。這會影響測試)。

僅觸發一個項目

然后,我認為不使用委托會更快地觸發一個特定項目上的事件。 這也是錯的:

http://jsperf.com/on-delegate-vs-not-trigger-one

不委托:慢80%

即使它不是最后一個兄弟姐妹,也是早期的兄弟姐妹之一,這是如此:

http://jsperf.com/on-delegate-vs-not-trigger-one-eq2

深度嵌套

最后,我認為委托完成的很多工作都必須是DOM樹解析。 這意味着在深度嵌套的DOM中使用委托並綁定到非常古老的祖先並且觸發比在深層嵌套的項本身上綁定和觸發花費更長的時間。

這最終證明是正確的:

http://jsperf.com/on-delegate-vs-not-deep-nesting

代表:慢90%

結論

我不能在這里得出任何具有重大意義的結論,但是如果你有大量的DOM可以使用,特別是如果它是深度嵌套的,你可以看一下使用委托進行綁定而不是直接綁定。

如果有的話,這些例子已經教會了我(好吧,無論如何都強化了)你應該嘗試讓委托元素盡可能接近將觸發事件的后代。

這是優化的問題。 讓我解釋:

$('#items2 .item a').on('click', function(e) {
  console.log("### Items2 click");
});

使用上面的代碼,每個錨都有自己的事件處理程序。 這是浪費內存,因為只有一個處理程序可以執行相同的操作。

$('#items').on('click', '.item a', function(e) {
  console.log("### Items click"); 
});

另外,對於第二個代碼,如果在綁定后向#items添加更多錨點,則無需添加新的事件處理程序。 父元素#items已經覆蓋了它們。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM