关于javascript:event.stoppropagation和event.preventdefault有什么区别?

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

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

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

为什么两者兼而有之?我应该继续检查两个吗?还是有区别?

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


stopPropagation茶泡上茶来代表事件从事件链。P></

preventDefaultprevents the action that makes the默认网络浏览器的事件。P></

让我们说你有P></

1
2
3
4
5
6
7
8
9
10
11
 <button id="but" />


$("#foo").click(function() {
   // mouse click on div
});

$("#but").click(function(ev) {
   // mouse click on button
   ev.stopPropagation();
});

exampleP></

1
2
3
4
5
6
7
8
$("#but").click(function(event){
  event.preventDefault();
 });


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

  <button id="but">button</button>

P></

1
2
3
4
5
6
7
8
$("#but").click(function(event){
  event.stopPropagation();
 });


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

  <button id="but">button</button>

P></

stopPropagationonly the is called the按钮单击处理程序不div和点击火灾。P></

如果你只是在preventDefaultonly as the action is but the browsers默认的函数是S的程序仍然div'点击火灾。P></

below are some on the DOM文档对象和事件从MDNMSDNP></

号码:P></

  • event.cancelBubble
  • event.preventDefault
  • event.returnValue
  • event.stopPropagation

for你可以只使用IE9和FF preventdefault &;stoppropagation。P></

to replace with stopPropagationIE8和支持下cancelBubble& replace with returnValuepreventDefaultP></


常用术语

从quirksmode.org:P></

Event capturing

When you use event capturing

1
2
3
4
5
6
7
8
               | |
---------------| |-----------------
| 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

1
2
3
4
5
6
7
8
               / \
---------------| |-----------------
| 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.

1
2
3
4
5
6
7
8
                 | |  / \
-----------------| |--| |-----------------
| element1       | |  | |                |
|   -------------| |--| |-----------     |
|   |element2    \ /  | |          |     |
|   --------------------------------     |
|        W3C event model                 |
------------------------------------------

接口

从w3.org,捕捉:for eventP></

If the capturing EventListener wishes to prevent further processing of
the event from occurring it may call the stopPropagation method of the
Event interface. This will prevent further dispatch of the event,
although additional EventListeners registered at the same hierarchy
level will still receive the event. Once an event's stopPropagation
method has been called, further calls to that method have no
additional effect. If no additional capturers exist and
stopPropagation has not been called, the event triggers the
appropriate EventListeners on the target itself.

泡:for eventP></

Any event handler may choose to prevent further event propagation by
calling the stopPropagation method of the Event interface. If any
EventListener calls this method, all additional EventListeners on the
current EventTarget will be triggered but bubbling will cease at that
level. Only one call to stopPropagation is required to prevent further
bubbling.

cancelation:for eventP></

Cancelation is accomplished by calling the Event's preventDefault
method. If one or more EventListeners call preventDefault during
any phase of event flow the default action will be canceled.

examples

在the following the examples,点击超链接在Web浏览器在线流(the the S触发器事件事件事件是listeners executed)和S(在默认target' action is opened表)。P></

HTML:P></

1
2
3
4
  Google

<p id="c">
</p>

JavaScript的:P></

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
var el = document.getElementById("c");

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

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

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

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

// 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);

实例1:在输出结果P></

1
2
3
4
DIV event capture
A event capture
A event bubbling
DIV event bubbling

实例2:增stopPropagation()to the functionP></

1
2
3
4
function capturingOnClick1(ev) {
    el.innerHTML +="DIV event capture";
    ev.stopPropagation();
}

在输出结果P></

1
DIV event capture

the event listener?向下盖上继续传播和prevented of the event。did not the不管一个人多页(默认行动,防止在开放的表)。P></

实例3:增stopPropagation()to the functionP></

1
2
3
4
function capturingOnClick2(ev) {
    el.innerHTML +="A event capture";
    ev.stopPropagation();
}

or the functionP></

1
2
3
4
function bubblingOnClick2(ev) {
    el.innerHTML +="A event bubbling";
    ev.stopPropagation();
}

在输出结果P></

1
2
3
DIV event capture
A event capture
A event bubbling

这都是因为listeners are the same on事件注册事件的目标。listeners the event of the prevented继续盖上传播的事件。did not the不管一个人多,防止他们的默认动作(在表开放)。P></

实例4:preventDefault()to any增函数,for instanceP></

1
2
3
4
function capturingOnClick1(ev) {
    el.innerHTML +="DIV event capture";
    ev.preventDefault();
}

prevents from opening在表。P></


返回错误;

当你称之为return false;时,它做了三件事:

  • event.preventDefault()–它停止浏览器的默认行为。
  • event.stopPropagation()–它防止事件传播(或"冒泡")DOM。
  • 停止回调执行并在调用时立即返回。
  • 请注意,此行为与普通(非jquery)事件处理程序不同,在正常(非jquery)事件处理程序中,return false不会阻止事件冒泡。

    preventDefault();

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

    何时使用它们?

    我们知道他们做什么,但什么时候使用他们?简单地说,这取决于你想完成什么。如果要"仅"阻止默认浏览器行为,请使用preventDefault();。如果要阻止默认浏览器行为并阻止事件传播DOM,请使用RETURN FALSE。在大多数情况下,你会使用返回错误;你真正想要的是preventDefault()

    实例:

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

    我们将看到纯javascript示例

    例1:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
      Click here to visit stackoverflow.com


      function executeChild() {
        alert('Link Clicked');
      }

      function executeParent() {
        alert('div Clicked');
      }

    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 Clicked Next you will get the javascript
    alert div Clicked and immediately you will be redirected to
    stackoverflow.com.

    例2:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
      Click here to visit stackoverflow.com


      function executeChild() {
        event.preventDefault();
        event.currentTarget.innerHTML = 'Click event prevented'
        alert('Link Clicked');
      }

      function executeParent() {
        alert('div Clicked');
      }

    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 Clicked Next you will get the javascript
    alert div Clicked 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 due > to event.preventDefault() method we used to prevent the default click
    action to be triggered.

    例3:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
      Click here to visit stackoverflow.com


      function executeChild() {
        event.stopPropagation();
        event.currentTarget.innerHTML = 'Click event prevented'
        alert('Link Clicked');
      }

      function executeParent() {
        alert('div Clicked');
      }

    This time if you click on Link the function executeParent() will not
    be called and you will not get the javascript alert div Clicked
    this 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.

    例4:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
      Click here to visit stackoverflow.com


      function executeChild() {
        event.preventDefault();
        event.stopPropagation();
        event.currentTarget.innerHTML = 'Click event prevented'
        alert('Link Clicked');
      }

      function executeParent() {
        alert('Div Clicked');
      }

    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.

    例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.

    案例:

  • 从内联事件处理程序返回false会阻止浏览器导航到链接地址,但它不会阻止事件通过DOM传播。
  • 从jquery事件处理程序返回false会阻止浏览器导航到链接地址,并阻止事件通过DOM传播。
  • 从常规的DOM事件处理程序返回false完全不起作用。
  • 将看到这三个例子。

  • 内联返回false。
  • 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
      Click here to visit stackoverflow.com


      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');
      }

  • 从jquery事件处理程序返回false。
  • 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">

      Click here to visit stackoverflow.com


      $('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');
      });

  • 从常规的DOM事件处理程序返回false。
  • 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
      Click here to visit stackoverflow.com


      function executeChild() {
        event.currentTarget.innerHTML = 'Click event prevented'
        alert('Link Clicked');
        return false
      }

      function executeParent() {
        alert('Div Clicked');
      }

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


    this from here is the配额P></

    event.preventdefaultP></

    the method prevents载preventdefault超时默认安事件从其功能性。你会使用preventdefault for example,停止在线安元,元clicking to the current page from离开:P></

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    //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!');
    };

    功能性element' while the s is the默认bricked continues to,the DOM事件的泡沫弹出。P></

    event.stoppropagationP></

    stoppropagation allows the second method,the,but to发生违约事件的功能性prevents事件蔓延:from theP></

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    //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 parent元素停止从knowing given its about a在线儿童事件。P></

    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.


    e.preventDefault()将阻止默认事件发生,e.stoppropagation()将阻止事件冒泡,返回false将同时执行这两项操作。

    event.stoppropagation()允许对同一元素执行其他处理程序,而event.stopImmediatePropagation()阻止每个事件运行。


    停止默认的action of the event.preventDefault();安元从发生。P></

    茶泡上event.stopPropagation();prevents from the DOM树的事件,从任何人handlers preventing parent of the notified event。P></

    for example,if there is a与点击链接附在DIVor method of a method that has also FORM点击附,它将防止DIVor from the method FORM点击射击。P></


    event.preventdefault-停止浏览器默认行为。现在出现了什么是浏览器默认行为。假设您有一个anchor标记,它有a href属性,并且这个anchor标记嵌套在一个有click事件的div标记中。锚点标记的默认行为是单击它应该导航的锚点标记时,但是event.preventDefault所做的是在这种情况下停止导航。但它从不停止事件的冒泡或事件的升级,即

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     Click Me!


    $('.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');
    });

    结果是

    "已单击元素"

    "已单击容器"

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    $('.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');
    });

    结果将是

    "已单击元素"

    有关详细信息,请参阅此链接https://codeplanet.io/preventdefault-vs-stoppropagation-vs-stoppimmediatepropagation/


    1
    2
    3
    4
    5
    6
    7
    8
    9
    $("#but").click(function(event){
    console.log("hello");
      event.preventDefault();
     });


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

      <button id="but">button</button>