在使用 Datatables 表格插件开发过程中,给每一列的表头增加了自定义的列筛选功能,具体是给表头增加了一个可点击的图标,点击图标触发筛选,但是发现点击图标的时候同时会触发 Datatables 自带的排序功能。
html 结构如下:
<th class=”_name indicator title sorting” tabindex=”0″ aria-controls=”table-abs” rowspan=”1″ colspan=”1″ style=”width: 250px;” aria-label=” 项目名称: activate to sort column ascending”>
项目名称
<!– 列筛选图标 –>
<i class=”addSelect” data-column=”1″><span class=”icon-caret-down”></span></i>
</th>
js 代码如下:
// 点击列筛选图标
$(‘.table-section’).off(‘.customSearch’).on(‘click.customSearch’, ‘th.title .addSelect’, function (evt) {
evt.stopPropagation();
// dosomething …
});
这种事件委托的事件绑定方式,在这里出现了事件冒泡,虽然调用了 evt.stopPropagation();,但仍然会触发绑定在 th.title 上的排序事件。
JS 事件代理不是基于事件冒泡么,如果委托元素和目标元素之间还有元素绑定了相同事件,如何阻止事件冒泡?— 知乎
实际上,事件委托的事件处理函数是当被委托的元素上的事件触发时判断 e.target 后执行,而不是目标元素上的事件被触发后就立即执行,在没有阻止冒泡的情况下,事件还是一层层传播的,只是处理函数在事件到达那一层被触发的问题。根据事件代理的规则,点击 li 元素后,click 事件是从 li 至 inner 至 outer 一层层冒泡上去的,沿途触发各个元素上的事件处理函数,如果我们将事件委托在 outer 上,即使调用了 stopPropagation,也只是阻止了事件从 outer 向上冒泡,而之前的冒泡过程必然会触发 inner 上的 click 事件,执行处理函数,但是如果将事件委托在 inner 上,并且阻止冒泡,阻止的是从 inner 开始的冒泡,这样就可以阻止 inner 及其祖先元素上的 click 事件被触发。
作者:echizen 链接:https://www.zhihu.com/questio…