0

例如,選項卡組件中的選項卡組件。我目前正在研究Titon Toolkit的下一個主要版本(https://github.com/titon/toolkit),2.0,並且我想盡可能輕鬆地支持這種情況。目前在1.0中,嵌套是不可能的。處理嵌套在組件中的組件的JS事件的最佳方法?

Toolkit中的組件使用事件委託來綁定組件內的交互。這些事件綁定到組件包裝器(頂級父代)並使用類委託給它中的所有子代(在2.0中它們使用CSS/JS分離的數據屬性)。現在你可以看到問題了。如果事件綁定到父組件,則它們也將被綁定到任何嵌套組件,以及它們共享相同的類名(或數據屬性)。此外,任何綁定到孩子的事件現在都會觸發2個事件,哦,不!

該問題的簡要示例。

<div class="tabs" id="tabs-1" data-tab> 
    <ul class="tab-nav" data-tab-nav> 
     <li><a href="">1</a></li> 
     <li><a href="">2</a></li> 
     <li><a href="">3</a></li> 
    </ul> 

    <section class="tab-section" data-tab-section></section> 
    <section class="tab-section" data-tab-section></section> 
    <section class="tab-section" data-tab-section> 

     <div class="tabs" id="tabs-2" data-tab> 
      <ul class="tab-nav" data-tab-nav> 
       <li><a href="">1</a></li> 
       <li><a href="">2</a></li> 
       <li><a href="">3</a></li> 
      </ul> 

      <section class="tab-section" data-tab-section></section> 
      <section class="tab-section" data-tab-section></section> 
      <section class="tab-section" data-tab-section></section> 
     </div> 

    </section> 
</div> 

隨着事件被綁定爲這樣:

$('#tabs-1').on('click', '[data-tab-nav] a', showSection); // Also being bound to #tabs-2 elements 
$('#tabs-2').on('click', '[data-tab-nav] a', showSection); 

這裏就是我的困境是什麼是最簡單的,或者更好的是,最不容易出錯的方法來解決這個?這是我目前唯一的解決方案。

  1. 在嵌套元素上綁定stopPropagation()。由於可能需要冒泡,因此不是一個好的解決方案,而且還需要開發人員處理。
  2. 將數據屬性與值一起使用。例如,初始化數據屬性爲[data-tab="foo"]的選項卡組件只會將事件綁定到具有相同數據屬性值的元素,例如[data-tab-nav="foo"] a。因此,如果父母爲foo而孩子爲bar,則所有內容都將被正確綁定。將需要更多的標記,但沒有缺陷。
  3. 在要綁定並可自定義的父級和子級中使用自定義類。

想法?建議?感謝您的輸入!

+0

還要注意,同樣的問題適用於通過對遍歷'找到()'。截至目前,第二個選項修復了事件綁定和遍歷。 – 2014-10-01 00:10:05

回答

0

這是我能想到這樣做的最簡單的方法(演示:http://jsfiddle.net/brdgc05d/3/):

var tabClasses = ['#tabs-1', '#tabs-2']; 

$.each(tabClasses, function(index, tabClass) { 
    $(tabClass).on('click', '[data-tab-nav] a', function(e) { 
     e.preventDefault(); 
     if ($(e.delegateTarget).parents('[data-tab]').length) { // must use delegateTarget, otherwise $(e.delegateTarget) would be the <a> element they clicked rather than $('#tabs-n') 
      // is a child, so you could abort the event here 
      alert(tabClass + ' clicked and IS a child'); 
     } else { 
      // is not a child 
      alert(tabClass + ' clicked and is NOT a child'); 
     } 
    }); 
});