【问题标题】:How to stopPropagation when there are multiple event delegations当有多个事件委托时如何停止传播
【发布时间】:2019-05-04 15:19:24
【问题描述】:

我有一个表格行,其中有一个元素具有委托给文档元素的事件处理程序,并且该行本身也有另一个委托给 tbody 元素的处理程序。如下代码:

// first part is defined in an initiating script file, so no jQuery used.
document.addEventListener('click', function(e) {
    var el = e.srcElement || e.target;

    if (el && el.classList && el.classList.contains('gotocontact')) {
        e.stopPropagation();
        alert('going to contact...')
    }
})
// second part is defined after the jQuery included...
$('#list').on('click', 'tr', function() {alert('click tr...')})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.0/jquery.min.js"></script>
<table class="table">
    <tbody id="list">
        <tr>
            <td><a class="gotocontact">John Doe</a></td>
            <td>Male</td>
        </tr>
        <tr>
            <td><a class="gotocontact">Jane Doe</a></td>
            <td>Female</td>
        </tr>
    </tbody>
</table>

我将 stopPropagation 放在那里,但它没有按预期工作:当我单击 a 元素时,不应触发 tr 处理程序。 任何人都可以提供一些提示?

【问题讨论】:

  • 为什么要混合使用 jQuery 和非 jQuery?选择一个并使用它。您在顶层停止传播,这在 tr 单击后触发,因此没有什么可以停止的。您无法阻止从较高事件触发的较低事件

标签: javascript jquery delegation


【解决方案1】:

如果你想阻止 jQuery 监听器触发,你应该在 capturing 阶段而不是在 bubbling 阶段调用stopPropagation,通过传递第三个@ 987654322@ 参数为addEventListener

document.addEventListener('click', function(e) {
    var el = e.srcElement || e.target;

    if (el && el.classList && el.classList.contains('gotocontact')) {
        e.stopPropagation();
        alert('going to contact...')
    }
}, true)
// ^^^^ add third parameter

$('#list').on('click', 'tr', function() {alert('click tr...')})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.0/jquery.min.js"></script>
<table class="table">
    <tbody id="list">
        <tr>
            <td><a class="gotocontact">John Doe</a></td>
            <td>Male</td>
        </tr>
        <tr>
            <td><a class="gotocontact">Jane Doe</a></td>
            <td>Female</td>
        </tr>
    </tbody>
</table>

【讨论】:

    【解决方案2】:

    在“tr”元素上添加的函数中添加 stopPropagation。应该可以的

    document.addEventListener('click', function (e) {
      var el = e.srcElement || e.target;
      if (el && el.classList && el.classList.contains('gotocontact')) {
      e.stopPropagation();
      alert('going to contact...')
     }
    })
    // second part is defined after the jQuery included...
    $('#list').on('click', 'tr', function (e) {
     e.stopPropagation();
     alert('click tr...')
    })
    

    【讨论】:

      【解决方案3】:

      实际上,这里的问题是在您的td 内部有a 标签,而a 标签的自然行为是它会将您带到新页面,因此不要使用e.stopPropagation(),而是使用e.preventDefault()。 希望,它可能对你有所帮助。您还可以在设置事件侦听器的第三个参数中传递 true。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-01-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-03-10
        • 1970-01-01
        相关资源
        最近更新 更多