Javascript event.stopPropagation 和 event.preventDefault 有什么区别?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5963669/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 19:42:20  来源:igfitidea点击:

What's the difference between event.stopPropagation and event.preventDefault?

javascripteventspreventdefaultstoppropagation

提问by Rudie

They seem to be doing the same thing...
Is one modern and one old? Or are they supported by different browsers?

他们似乎在做同样的事情……
一个现代的一个古老的?或者它们是否受不同浏览器的支持?

When I handle events myself (without framework) I just always check for both and execute both if present. (I also return false, but I have the feeling that doesn't work with events attached with node.addEventListener).

当我自己处理事件(没有框架)时,我总是检查两者并执行两者(如果存在)。(我也有return false,但我有一种感觉,不适用于带有 的事件node.addEventListener)。

So why both? Should I keep checking for both? Or is there actually a difference?

那么为什么两者都有呢?我应该继续检查两者吗?或者实际上有区别吗?

(I know, a lot of questions, but they're all sort of the same =))

(我知道,很多问题,但它们都是一样的=))

回答by Raynos

stopPropagationstops the event from bubbling up the event chain.

stopPropagation阻止事件在事件链上冒泡。

preventDefaultprevents the default action the browser makes on that event.

preventDefault阻止浏览器对该事件进行的默认操作。

Examples

例子

preventDefault

防止违约

$("#but").click(function (event) {
  event.preventDefault()
})
$("#foo").click(function () {
  alert("parent click event fired!")
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="foo">
  <button id="but">button</button>
</div>

stopPropagation

停止传播

$("#but").click(function (event) {
  event.stopPropagation()
})
$("#foo").click(function () {
  alert("parent click event fired!")
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="foo">
  <button id="but">button</button>
</div>

With stopPropagation, only the button's click handleris called while the div's click handlernever fires.

随着stopPropagation,只有button的点击处理程序被调用,而div的点击处理程序永远不会触发。

Where as if you use preventDefault, only the browser's default action is stopped but the div's click handler still fires.

如果您使用preventDefault,则仅停止浏览器的默认操作,但 div 的单击处理程序仍会触发。

Below are some docs on the DOM event properties and methods from MDN:

下面是一些来自 MDN 的关于 DOM 事件属性和方法的文档:

For IE9 and FF you can just use preventDefault & stopPropagation.

对于 IE9 和 FF,您可以只使用 preventDefault 和 stopPropagation。

To support IE8 and lower replace stopPropagationwith cancelBubbleand replace preventDefaultwith returnValue

支持IE8及以下的replace stopPropagationwithcancelBubble和replace preventDefaultwithreturnValue

回答by Ashkan

Terminology

术语

From quirksmode.org:

来自quirksmode.org

Event capturing

When you use event capturing

               | |
---------------| |-----------------
| element1     | |                |
|   -----------| |-----------     |
|   |element2  \ /          |     |
|   -------------------------     |
|        Event CAPTURING          |
-----------------------------------

the event handler of element1 fires first, the event handler of element2 fires last.

Event bubbling

When you use event bubbling

               / \
---------------| |-----------------
| element1     | |                |
|   -----------| |-----------     |
|   |element2  | |          |     |
|   -------------------------     |
|        Event BUBBLING           |
-----------------------------------

the event handler of element2 fires first, the event handler of element1 fires last.

Any event taking place in the W3C event model is first captured until it reaches the target element and then bubbles up again.

                 | |  / \
-----------------| |--| |-----------------
| element1       | |  | |                |
|   -------------| |--| |-----------     |
|   |element2    \ /  | |          |     |
|   --------------------------------     |
|        W3C event model                 |
------------------------------------------

事件捕捉

使用事件捕获时

               | |
---------------| |-----------------
| element1     | |                |
|   -----------| |-----------     |
|   |element2  \ /          |     |
|   -------------------------     |
|        Event CAPTURING          |
-----------------------------------

element1 的事件处理程序首先触发,element2 的事件处理程序最后触发。

事件冒泡

当你使用事件冒泡时

               / \
---------------| |-----------------
| element1     | |                |
|   -----------| |-----------     |
|   |element2  | |          |     |
|   -------------------------     |
|        Event BUBBLING           |
-----------------------------------

element2 的事件处理程序首先触发,element1 的事件处理程序最后触发。

在 W3C 事件模型中发生的任何事件首先被捕获,直到它到达目标元素,然后再次冒泡

                 | |  / \
-----------------| |--| |-----------------
| element1       | |  | |                |
|   -------------| |--| |-----------     |
|   |element2    \ /  | |          |     |
|   --------------------------------     |
|        W3C event model                 |
------------------------------------------

Interface

界面

From w3.org, for event capture:

来自w3.org,用于事件捕获

If the capturing EventListenerwishes to prevent further processing of the event from occurring it may call the stopPropagationmethod of the Eventinterface. This will prevent further dispatch of the event, although additional EventListenersregistered at the same hierarchy level will still receive the event. Once an event's stopPropagationmethod has been called, further calls to that method have no additional effect. If no additional capturers exist and stopPropagationhas not been called, the event triggers the appropriate EventListenerson the target itself.

如果捕获EventListener希望阻止对事件的进一步处理,它可以调用接口的stopPropagation方法 Event。这将阻止事件的进一步分派,尽管EventListeners在同一层次结构级别的其他注册仍将接收该事件。一旦stopPropagation调用了事件的方法,对该方法的进一步调用就没有额外的效果。如果没有额外的捕获器存在 stopPropagation且未被调用,则该事件会EventListeners在目标本身上触发相应的事件。

For event bubbling:

对于事件冒泡

Any event handler may choose to prevent further event propagation by calling the stopPropagationmethod of the Eventinterface. If any EventListenercalls this method, all additional EventListenerson the current EventTargetwill be triggered but bubbling will cease at that level. Only one call to stopPropagationis required to prevent further bubbling.

任何事件处理程序都可以选择通过调用接口的stopPropagation方法来阻止进一步的事件传播Event。如果有任何 EventListener调用此方法,则将触发EventListeners当前的所有附加内容,EventTarget但在该级别将停止冒泡。只需要一次调用以stopPropagation防止进一步冒泡。

For event cancelation:

对于活动取消

Cancelation is accomplished by calling the Event's preventDefaultmethod. If one or more EventListenerscall preventDefaultduring any phase of event flow the default action will be canceled.

取消是通过调用EventpreventDefault方法完成的。如果在事件流的任何阶段有一个或多个EventListeners调用preventDefault,默认操作将被取消。

Examples

例子

In the following examples, a click on the hyperlink in the web browser triggers the event's flow (the event listeners are executed) and the event target's default action (a new tab is opened).

在以下示例中,单击 Web 浏览器中的超链接会触发事件流(执行事件侦听器)和事件目标的默认操作(打开一个新选项卡)。

HTML:

HTML:

<div id="a">
  <a id="b" href="http://www.google.com/" target="_blank">Google</a>
</div>
<p id="c"></p>

JavaScript:

JavaScript:

var el = document.getElementById("c");

function capturingOnClick1(ev) {
    el.innerHTML += "DIV event capture<br>";
}

function capturingOnClick2(ev) {
    el.innerHTML += "A event capture<br>";
}

function bubblingOnClick1(ev) {
    el.innerHTML += "DIV event bubbling<br>";
}

function bubblingOnClick2(ev) {
    el.innerHTML += "A event bubbling<br>";
}

// The 3rd parameter useCapture makes the event listener capturing (false by default)
document.getElementById("a").addEventListener("click", capturingOnClick1, true);
document.getElementById("b").addEventListener("click", capturingOnClick2, true);
document.getElementById("a").addEventListener("click", bubblingOnClick1, false);
document.getElementById("b").addEventListener("click", bubblingOnClick2, false);

Example 1: it results in the output

示例 1:它导致输出

DIV event capture
A event capture
A event bubbling
DIV event bubbling

Example 2: adding stopPropagation()to the function

示例 2:添加stopPropagation()到函数

function capturingOnClick1(ev) {
    el.innerHTML += "DIV event capture<br>";
    ev.stopPropagation();
}

results in the output

结果在输出

DIV event capture

The event listener prevented further downward and upward propagation of the event. However it did not prevent the default action (a new tab opening).

事件侦听器阻止了事件的进一步向下和向上传播。但是它并没有阻止默认操作(打开新标签页)。

Example 3: adding stopPropagation()to the function

示例 3:添加stopPropagation()到函数

function capturingOnClick2(ev) {
    el.innerHTML += "A event capture<br>";
    ev.stopPropagation();
}

or the function

或函数

function bubblingOnClick2(ev) {
    el.innerHTML += "A event bubbling<br>";
    ev.stopPropagation();
}

results in the output

结果在输出

DIV event capture
A event capture
A event bubbling

This is because both event listeners are registered on the same event target. The event listeners prevented further upward propagation of the event. However they did not prevent the default action (a new tab opening).

这是因为两个事件侦听器都注册在同一个事件目标上。事件侦听器阻止了事件的进一步向上传播。但是,它们并没有阻止默认操作(打开新选项卡)。

Example 4: adding preventDefault()to any function, for instance

示例 4:添加preventDefault()到任何函数,例如

function capturingOnClick1(ev) {
    el.innerHTML += "DIV event capture<br>";
    ev.preventDefault();
}

prevents a new tab from opening.

防止打开新标签页。

回答by Keval Bhatt

return false;

返回假;



return false;does 3 separate things when you call it:

return false;当你调用它时会做 3 件不同的事情:

  1. event.preventDefault()– It stops the browsers default behaviour.
  2. event.stopPropagation()– It prevents the event from propagating (or “bubbling up”) the DOM.
  3. Stops callback execution and returns immediately when called.
  1. event.preventDefault()– 它停止浏览器的默认行为。
  2. event.stopPropagation()– 它可以防止事件传播(或“冒泡”)DOM。
  3. 停止回调执行并在调用时立即返回。

Note that this behaviour differs from normal (non-jQuery) event handlers, in which, notably, return falsedoes not stop the event from bubbling up.

请注意,此行为与普通(非 jQuery)事件处理程序不同,在普通(非 jQuery)事件处理程序中,值得注意的是,return false它不会阻止事件冒泡。

preventDefault();

防止默认();



preventDefault();does one thing: It stops the browsers default behaviour.

preventDefault();做一件事:它停止浏览器的默认行为。

When to use them?

什么时候使用它们?



We know what they do but when to use them? Simply it depends on what you want to accomplish. Use preventDefault();if you want to “just” prevent the default browser behaviour. Use return false; when you want to prevent the default browser behaviour and prevent the event from propagating the DOM. In most situations where you would use return false; what you really want is preventDefault().

我们知道它们做什么,但什么时候使用它们?简单地说,这取决于你想要完成什么。使用preventDefault();,如果你想“只是”防止默认浏览器的行为。使用 return false; 当您想要阻止默认浏览器行为并阻止事件传播 DOM 时。在大多数情况下,您将使用 return false;你真正想要的是preventDefault()

Examples:

例子:



Let's try to understand with examples:

让我们试着用例子来理解:

We will see pure JAVASCRIPT example

我们将看到纯 JAVASCRIPT 示例

Example 1:

示例 1:

<div onclick='executeParent()'>
  <a href='https://stackoverflow.com' onclick='executeChild()'>Click here to visit stackoverflow.com</a>
</div>
<script>
  function executeChild() {
    alert('Link Clicked');
  }

  function executeParent() {
    alert('div Clicked');
  }
</script>

Run the above code you will see the hyperlink ‘Click here to visit stackoverflow.com‘now if you click on that link first you will get the javascript alert Link ClickedNext you will get the javascript alert div Clickedand immediately you will be redirected to stackoverflow.com.

运行上面的代码,您现在将看到“单击此处访问 stackoverflow.com”的超链接,如果您首先单击该链接,您将获得 javascript 警报链接 单击下一步您将获得 javascript 警报div 单击,然后您将立即被重定向到stackoverflow.com。

Example 2:

示例 2:

<div onclick='executeParent()'>
  <a href='https://stackoverflow.com' onclick='executeChild()'>Click here to visit stackoverflow.com</a>
</div>
<script>
  function executeChild() {
    event.preventDefault();
    event.currentTarget.innerHTML = 'Click event prevented'
    alert('Link Clicked');
  }

  function executeParent() {
    alert('div Clicked');
  }
</script>

Run the above code you will see the hyperlink ‘Click here to visit stackoverflow.com‘ now if you click on that link first you will get the javascript alert Link ClickedNext you will get the javascript alert div ClickedNext you will see the hyperlink ‘Click here to visit stackoverflow.com‘ replaced by the text ‘Click event prevented‘ and you will notbe redirected to stackoverflow.com. This is due > to event.preventDefault() method we used to prevent the default click action to be triggered.

运行上面的代码,您现在将看到“单击此处访问 stackoverflow.com”的超链接,如果您先单击该链接,您将获得 javascript 警报链接 单击下一步您将获得 javascript 警报div 单击下一步您将看到超链接 '单击此处访问 stackoverflow.com' 替换为文本“阻止的单击事件”,您将不会被重定向到 stackoverflow.com。这是由于 > 我们用来防止触发默认点击操作的 event.preventDefault() 方法。

Example 3:

示例 3:

<div onclick='executeParent()'>
  <a href='https://stackoverflow.com' onclick='executeChild()'>Click here to visit stackoverflow.com</a>
</div>
<script>
  function executeChild() {
    event.stopPropagation();
    event.currentTarget.innerHTML = 'Click event prevented'
    alert('Link Clicked');
  }

  function executeParent() {
    alert('div Clicked');
  }
</script>

This time if you click on Link the function executeParent() will not be called and you will not get the javascript alert div Clickedthis time. This is due to us having prevented the propagation to the parent div using event.stopPropagation() method. Next you will see the hyperlink ‘Click here to visit stackoverflow.com‘ replaced by the text ‘Click event is going to be executed‘ and immediately you will be redirected to stackoverflow.com. This is because we haven't prevented the default click action from triggering this time using event.preventDefault() method.

这次如果您点击链接,函数 executeParent() 将不会被调用,您将不会获得 javascript 警报div Clicked这次。这是因为我们使用 event.stopPropagation() 方法阻止了传播到父 div。接下来,您将看到超链接“单击此处访问 stackoverflow.com”被文本“将要执行单击事件”替换,并且您将立即被重定向到 stackoverflow.com。这是因为我们没有使用 event.preventDefault() 方法阻止默认点击操作这次触发。

Example 4:

示例 4:

<div onclick='executeParent()'>
  <a href='https://stackoverflow.com' onclick='executeChild()'>Click here to visit stackoverflow.com</a>
</div>
<script>
  function executeChild() {
    event.preventDefault();
    event.stopPropagation();
    event.currentTarget.innerHTML = 'Click event prevented'
    alert('Link Clicked');
  }

  function executeParent() {
    alert('Div Clicked');
  }
</script>

If you click on the Link, the function executeParent() will not be called and you will not get the javascript alert. This is due to us having prevented the propagation to the parent div using event.stopPropagation() method. Next you will see the hyperlink ‘Click here to visit stackoverflow.com‘ replaced by the text ‘Click event prevented‘ and you will not be redirected to stackoverflow.com. This is because we have prevented the default click action from triggering this time using event.preventDefault() method.

如果您单击链接,则不会调用函数 executeParent() 并且您不会收到 javascript 警报。这是因为我们使用 event.stopPropagation() 方法阻止了传播到父 div。接下来,您将看到超链接“单击此处访问 stackoverflow.com”被文本“阻止单击事件”替换,并且您不会被重定向到 stackoverflow.com。这是因为我们使用 event.preventDefault() 方法阻止了这次触发默认点击操作。

Example 5:

示例 5:

For return false I have three examples and all appear to be doing the exact same thing (just returning false), but in reality the results are quite different. Here's what actually happens in each of the above.

对于 return false,我有三个示例,它们似乎都在做完全相同的事情(只是返回 false),但实际上结果却大不相同。以下是上述每一项中实际发生的情况。

cases:

案例:

  1. Returning falsefrom an inline event handler prevents the browser from navigating to the link address, but it doesn't stop the event from propagating through the DOM.
  2. Returning falsefrom a jQuery event handler prevents the browser from navigating to the link address and it stops the event from propagating through the DOM.
  3. Returning falsefrom a regular DOM event handler does absolutely nothing.
  1. 从内联事件处理程序返回false 会阻止浏览器导航到链接地址,但不会阻止事件通过 DOM 传播。
  2. 从 jQuery 事件处理程序返回false 会阻止浏览器导航到链接地址,并阻止事件通过 DOM 传播。
  3. 从常规 DOM 事件处理程序返回false绝对没有任何作用。

Will see all three example.

将看到所有三个示例。

  1. Inline return false.
  1. 内联返回假。

<div onclick='executeParent()'>
  <a href='https://stackoverflow.com' onclick='return false'>Click here to visit stackoverflow.com</a>
</div>
<script>
  var link = document.querySelector('a');

  link.addEventListener('click', function() {
    event.currentTarget.innerHTML = 'Click event prevented using inline html'
    alert('Link Clicked');
  });


  function executeParent() {
    alert('Div Clicked');
  }
</script>

  1. Returning falsefrom a jQuery event handler.
  1. 从 jQuery 事件处理程序返回false

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
  <a href='https://stackoverflow.com'>Click here to visit stackoverflow.com</a>
</div>
<script>
  $('a').click(function(event) {
    alert('Link Clicked');
    $('a').text('Click event prevented using return FALSE');
    $('a').contents().unwrap();
    return false;
  });
  $('div').click(function(event) {
    alert('Div clicked');
  });
</script>

  1. Returning false from a regular DOM event handler.
  1. 从常规 DOM 事件处理程序返回 false。

<div onclick='executeParent()'>
  <a href='https://stackoverflow.com' onclick='executeChild()'>Click here to visit stackoverflow.com</a>
</div>
<script>
  function executeChild() {
    event.currentTarget.innerHTML = 'Click event prevented'
    alert('Link Clicked');
    return false
  }

  function executeParent() {
    alert('Div Clicked');
  }
</script>

Hope these examples are clear. Try executing all these examples in a html file to see how they work.

希望这些例子是清楚的。尝试在 html 文件中执行所有这些示例,看看它们是如何工作的。

回答by VladL

This is the quote from here

这是这里的报价

Event.preventDefault

Event.preventDefault

The preventDefault method prevents an event from carrying out its default functionality. For example, you would use preventDefault on an A element to stop clicking that element from leaving the current page:

preventDefault 方法阻止事件执行其默认功能。例如,您可以在 A 元素上使用 preventDefault 来阻止单击该元素离开当前页面:

//clicking the link will *not* allow the user to leave the page 
myChildElement.onclick = function(e) { 
    e.preventDefault(); 
    console.log('brick me!'); 
};

//clicking the parent node will run the following console statement because event propagation occurs
logo.parentNode.onclick = function(e) { 
    console.log('you bricked my child!'); 
};

While the element's default functionality is bricked, the event continues to bubble up the DOM.

虽然元素的默认功能被阻止,但该事件继续在 DOM 中冒泡。

Event.stopPropagation

事件停止传播

The second method, stopPropagation, allows the event's default functionality to happen but prevents the event from propagating:

第二种方法 stopPropagation 允许事件的默认功能发生但阻止事件传播:

//clicking the element will allow the default action to occur but propagation will be stopped...
myChildElement.onclick = function(e) { 
    e.stopPropagation();
    console.log('prop stop! no bubbles!'); 
};

//since propagation was stopped by the child element's onClick, this message will never be seen!
myChildElement.parentNode.onclick = function(e) { 
    console.log('you will never see this message!'); 
};

stopPropagation effectively stops parent elements from knowing about a given event on its child.

stopPropagation 有效地阻止父元素了解其子元素上的给定事件。

While a simple stop method allows us to quickly handle events, it's important to think about what exactly you want to happen with bubbling. I'd bet that all a developer really wants is preventDefault 90% of the time! Incorrectly "stopping" an event could cause you numerous troubles down the line; your plugins may not work and your third party plugins could be bricked. Or worse yet -- your code breaks other functionality on a site.

虽然简单的 stop 方法允许我们快速处理事件,但重要的是要考虑冒泡到底要发生什么。我敢打赌,开发人员真正想要的是在 90% 的情况下都防止默认!错误地“停止”事件可能会给您带来许多麻烦;您的插件可能无法正常工作,并且您的第三方插件可能会变砖。或者更糟——您的代码破坏了站点上的其他功能。

回答by Nayas Subramanian

Event.preventDefault- stops browser default behaviour. Now comes what is browser default behaviour. Assume you have a anchor tag and it has got a href attribute and this anchor tag is nested inside a div tag which has got a click event. Default behaviour of anchor tag is when clicked on the anchor tag it should navigate, but what event.preventDefault does is it stops the navigation in this case. But it never stops the bubbling of event or escalation of event i.e

Event.preventDefault- 停止浏览器默认行为。现在是浏览器默认行为。假设你有一个锚标签,它有一个 href 属性,这个锚标签嵌套在一个有点击事件的 div 标签内。锚标记的默认行为是单击它应该导航的锚标记时,但 event.preventDefault 在这种情况下会停止导航。但它永远不会停止事件的冒泡或事件的升级,即

<div class="container">
 <a href="#" class="element">Click Me!</a>
</div>

$('.container').on('click', function(e) {
 console.log('container was clicked');
});

$('.element').on('click', function(e) {
  e.preventDefault(); // Now link won't go anywhere
  console.log('element was clicked');
});

The result will be

结果将是

"element was clicked"

“元素被点击”

"container was clicked"

“容器被点击”

Now event.StopPropation it stops bubbling of event or escalation of event. Now with above example

现在 event.StopPropation 它停止冒泡事件或事件升级。现在有了上面的例子

$('.container').on('click', function(e) {
  console.log('container was clicked');
});

$('.element').on('click', function(e) {
  e.preventDefault(); // Now link won't go anywhere
  e.stopPropagation(); // Now the event won't bubble up
 console.log('element was clicked');
});

Result will be

结果将是

"element was clicked"

“元素被点击”

For more info refer this link https://codeplanet.io/preventdefault-vs-stoppropagation-vs-stopimmediatepropagation/

有关更多信息,请参阅此链接 https://codeplanet.io/preventdefault-vs-stoppropagation-vs-stopimmediatepropagation/

回答by Mike Clark

event.preventDefault();Stops the default action of an element from happening.

event.preventDefault();阻止元素的默认操作发生。

event.stopPropagation();Prevents the event from bubbling up the DOM tree, preventing any parent handlers from being notified of the event.

event.stopPropagation();防止事件在 DOM 树中冒泡,从而防止任何父处理程序收到该事件的通知。

For example, if there is a link with a click method attached inside of a DIVor FORMthat also has a click method attached, it will prevent the DIVor FORMclick method from firing.

例如,如果在 a 中附加了一个带有 click 方法的链接,DIV或者FORM也附加了一个 click 方法,那么它将阻止触发DIVFORM单击方法。

回答by Manish Singh

$("#but").click(function(event){
console.log("hello");
  event.preventDefault();
 });


$("#foo").click(function(){
 alert("parent click event fired !");
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="foo">
  <button id="but">button</button>
</div>