当我在提交按钮级别停止传播时,为什么会触发表单提交事件?

Why does the form submit event fire when I have stopped propagation at the submit button level?

HTML

<form>
    <input type='text'>
    <button type='submit'>Submit</button>
</form>

JavaScript

$('form').on('submit', function(e) {
    alert('submit');
    e.preventDefault();
});

$('button').on('click', function(e) {
    e.stopPropagation();
    alert('clicked');
});

Fiddle


看完很棒的视频here,我了解到当我点击提交按钮时,事件冒泡到表单,然后触发表单的提交事件。这解释了为什么 "clicked" 在 "submit" 之前被提醒(在我将 e.stopPropagation() 添加到按钮处理程序之前)。

但是当我将 e.stopPropagation() 添加到按钮处理程序时,"submit" 仍然会收到警报。为什么?我认为 stopPropagation 阻止事件冒泡到 form,因此 form.on('submit') 侦听器不应该是 "hearing" 事件。

您还需要 e.preventDefault(); 在按钮点击中:

$('form').on('submit', function(e) {
    alert('submit');
    e.preventDefault();
});

$('button').on('click', function(e) {
    e.preventDefault();
    alert('clicked');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form>
    <input type='text'/>
    <button type='submit'>Submit</button>
</form>

查看处理程序

$('button').on('click', function(e) {
    e.stopPropagation();

请注意,该事件是 click,因此您要阻止 click 事件向上传播链,并且它根本不会与 submit 事件交互,它仍然会触发,因为提交按钮的默认操作是提交表单,而停止它的方法是使用 preventDefault

来阻止该默认操作

换句话说,stopPropagation 仅阻止正在处理的当前事件传播到父元素,它不会阻止元素的默认行为,即 preventDefault !

当您单击表单中的提交按钮时,单击事件会在按钮上产生并冒泡。提交事件在表单(而不是按钮)上产生并从那里冒泡。

如果您停止对点击事件的传播,您只是停止了点击事件的冒泡阶段。这对提交事件没有影响。

要停止提交操作,您必须向提交处理程序添加一个检查。

请记住,在按钮的点击处理程序上添加 e.preventDefault() 不足以阻止提交事件的产生,因为提交表单的方式比点击按钮更多。 (例如,在输入字段中按 enter)。