例如,选项卡组件中的一个选项卡组件。我目前正在开发Titon Toolkit(https://github.com/titon/toolkit)的下一个主要版本2.0,我想尽可能轻松地支持这种情况。当前在1.0中,无法嵌套。
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);
这是我所处的困境。解决这个问题的最简单或更好的是,最不容易出错的方法是什么?这些是我目前仅有的解决方案。
stopPropagation()
。这不是一个很好的解决方案,因为可能需要冒泡,并且也需要由开发人员处理。[data-tab="foo"]
初始化选项卡组件将仅将事件绑定到具有相同数据属性值的元素,例如[data-tab-nav="foo"] a
。因此,如果父级为foo
,子级为bar
,则所有内容都将正确绑定。将需要更多的标记,但没有缺点。有什么想法?有什么建议吗?
这是我想到的最简单的方法(演示: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');
}
});
});