为何stopPropagation会阻止同一元素的绑定事件?代码异常求助
需求
- 给同一元素绑定两个点击事件,确保两者都能触发
- 阻止事件向DOM层级的父元素传播(父元素绑定的事件不应触发)
问题描述
绑定两个事件后,仅第一个事件触发,第二个完全没执行。代码已复现该场景:
JavaScript代码
$('.main').on('click', '.testedDiv', function() { alert('div clicked #1'); e.stopPropagation(); }); $('.main').on('click', '.testedDiv', function() { alert('div clicked #2'); e.stopPropagation(); }); $('.main').on('click', 'span', function() { alert('span clicked'); });
HTML代码
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script> <div class="main"> <div class="testedDiv"> DIV <span> Span </span> </div> </div>
现象与预期
- 实际现象:仅弹出
div clicked #1的提示,第二个事件无响应 - 预期:两个
div clicked的提示都弹出,同时阻止事件冒泡到父元素
根据W3Schools对stopPropagation的描述:
Propagation means bubbling up to parent elements or capturing down to child elements.
以及MDN对stopImmediatePropagation的描述:
If several listeners are attached to the same element for the same event type, they are called in the order in which they were added. If stopImmediatePropagation() is invoked during one such call, no remaining listeners will be called, either on that element or any other element.
代码表现得像调用了stopImmediatePropagation(),但实际并未使用,请问忽略了什么?
问题原因与解决方法
你忽略了事件处理函数的参数声明:在两个.testedDiv的点击事件中,你直接使用了e.stopPropagation(),但函数参数里没有声明e。这会导致e未定义,调用stopPropagation()时抛出错误,中断JavaScript执行流程,第二个事件监听根本没机会触发。
修正后的代码
// 声明事件参数e $('.main').on('click', '.testedDiv', function(e) { alert('div clicked #1'); e.stopPropagation(); }); $('.main').on('click', '.testedDiv', function(e) { alert('div clicked #2'); e.stopPropagation(); }); $('.main').on('click', 'span', function() { alert('span clicked'); });
说明
- 正确声明事件参数
e后,stopPropagation()只会阻止事件向父元素冒泡,不会影响同一元素上的其他事件监听,两个事件会按绑定顺序依次触发 - 如果想要阻止同一元素后续的事件监听执行,才需要使用
e.stopImmediatePropagation(),你的场景不需要这个方法
内容的提问来源于stack exchange,提问作者Piotrek

