32

In the vue docs under Event Modifiers, there's an example of a modifier called capture which states the following:

<!-- use capture mode when adding the event listener -->
<div v-on:click.capture="doThis">...</div>

I've done some searching, but haven't found a clear answer as to how this modifies the event binding, then I thought to myself 'You know who always has the answer? Stack Overflow'

tony19
  • 125,647
  • 18
  • 229
  • 307
autoboxer
  • 1,358
  • 1
  • 16
  • 37

2 Answers2

25

So right after posting I stumbled on this article which illustrates it clearly. Let's say for this example that you have three elements nested within each other:

<div class="outer">
    <div class="middle">
        <div class="inner"></div>
    </div>
</div>

When a click event occurs, there are two phases: the first is called capturing, the second is called bubbling. When you click on the .inner, the event traverses down from the outermost container element .outer, to .middle, then to .inner in the capturing phase, then from .inner to .middle, then to .outer in the bubbling phase.

If capture is set on .inner for a click event handler:

<div class="outer">
    <div class="middle">
        <div class="inner" v-on:click.capture="doThis"></div>
    </div>
</div>

and you click on it, it will hit .outer, then .middle, then .inner in the capture phase, which will cause doThis(...) to be called, after which the bubbling phase begins.

If capture is set on .middle for a click event handler

<div class="outer">
    <div class="middle" v-on:click.capture="doThis">
        <div class="inner"></div>
    </div>
</div>

and you click on it, it will hit .outer, then .middle, in the capture phase, which will cause doThis(...) to be called, then hit .inner in the capture phase, after which the bubbling phase begins.

Edit: Thanks for all the great responses below, I've amended the answer to fix where I was incorrect.

autoboxer
  • 1,358
  • 1
  • 16
  • 37
  • 1
    just to clarify, would the event actually be called (at least) 5 times, because it will be called on `` and `` tags too? Or does Vue consider capture mode to apply only within its instance's root element? – Michael Johnston Apr 27 '17 at 18:09
  • 16
    This answer is incorrect. Each element's event handler will be triggered only once, the difference is when it's triggered (before it's child or after it's child). Capture mode triggers before the child. Bubble mode (the default), after the child. You can even put a capture mode and bubble mode event handler like
    – absolutelyNoWarranty May 25 '17 at 03:03
  • 2
    This fiddle demonstrates how a single click to inner can trigger a maximum of 6 event handlers. https://jsfiddle.net/7uvh0fnz/1 – absolutelyNoWarranty May 25 '17 at 03:24
  • 1
    I agree with @absolutelyNoWarranty it is noting to do with number of execution of that event listener but when that even listener get executed compare to its predecessor's and ancestor's even listener – Sohail Faruqui Aug 06 '17 at 13:28
  • @absolutelyNoWarranty You should post your jsfiddle code that disproves this answer as a separate answer here. It's a really helpful demo. – MarredCheese Jul 23 '19 at 18:56
17

Both bubble and capture event handlers on an element will be triggered only once, the difference is when they are triggered (before the children or after the children). Capture mode means the handler is triggered before any handlers on child elements. Bubble mode (the default), means the handler is triggered after all child elements have finished their handlers. You can even put a capture mode and bubble mode event handler by doing <div v-on:click="doThis" v-on:click.capture="doThis">

This JS fiddle demonstrates how a single click to a nested inner element first triggers capture handlers in an "outer-to-inner" order, and then triggers bubble handlers in an "inner-to-outer" order.

absolutelyNoWarranty
  • 1,888
  • 2
  • 17
  • 17