How to Understand Usecapture Parameter in Addeventlistener

Unable to understand useCapture parameter in addEventListener

Events can be activated at two occasions: At the beginning ("capture"), and at the end ("bubble").

Events are executed in the order of how they're defined. Say, you define 4 event listeners:

window.addEventListener("click", function(){console.log(1)}, false);window.addEventListener("click", function(){console.log(2)}, true);window.addEventListener("click", function(){console.log(3)}, false);window.addEventListener("click", function(){console.log(4)}, true);

useCapture in addEventListener behaves strangely

Bubbling/capturing only relevant when an event bubbles/captures to a target element, not when the event is triggered directly on that element (this is the "target phase" of W3C events model). In the case that there is no "bubble" or "capture" — which is the case with the click event on your <button> — the events are processed in the order they are added.

For example, if you were to reverse the order of the listeners on your "wrapper" and click on the wrapper element (not the button) you would notice the same behavior (bubble would fire first):

// 1. "Wrapper Bubble" 2. "Wrapper Capture"
document.getElementById('wrapper').addEventListener('click', function () { console.log('Wrapper bubble'); }, false);
document.getElementById('wrapper').addEventListener('click', function () { console.log('Wrapper capture'); }, true);

However, if you were to use the same order (bubble before capture) and click on the button the capture will fire before bubble. This is because the "click" event is being triggered on the button and is "captured down" through the dom before "bubbling up" (the normal event flow).

I've created a JSBIN that will hopefully help clarify this (however, it may just add to the confusion). The "ordered" button / div triggers the order of your 1st snippet, and the "unordered" button and div use the order in you 2nd.

For additional info see this SO answer and the W3C Event Flow documentation, specifically the Target Phase.

EventTarget.addEventListener()'s useCapture argument use?

I think this diagram from the DOM events specification pretty much says it all:

Sample Image

Basically: The useCapture argument is used to receive notification during the capture phase, rather than the bubbling phase. A capturing-phase handler will be called before any bubbling-phase handler. Note that Internet Explorer didn't support the capturing phase prior to IE9.

So a better example is two handlers on the same element, in the middle (but let's do all three levels for completeness):

hook("container", "- ");hook("wrapper",   "  - ");hook("testBtn",   "    - ");
function hook(id, prefix) { var element = document.getElementById(id); element.addEventListener("click", function(e) { display(id + "'s capturing handler called", prefix); }, true); element.addEventListener("click", function(e) { display(id + "'s bubbling called", prefix); }, false);}
function display(msg, prefix) { var p = document.createElement('p'); p.innerHTML = (prefix || "") + msg; document.body.appendChild(p);}
#container, #wrapper {  padding : 10px;  border : 1px solid green;}p {  font-family: sans-serif;  padding: 0;  margin: 0;}
<div id="container"> <div id="wrapper">   <button id="testBtn">A button</button> </div></div>

What does the third parameter (false) indicate in document.addEventListener(deviceready,OnDeviceReady,false);

It's useCapture:

If true, useCapture indicates that the user wishes to
initiate capture. After initiating
capture, all events of the specified
type will be dispatched to the
registered listener before being
dispatched to any EventTargets beneath
it in the DOM tree. Events which are
bubbling upward through the tree will
not trigger a listener designated to
use capture. See DOM Level 3 Events
for a detailed explanation.

Using event listener should we use useCapture as false to support old browser or it will be used as default for every browser

As mentioned in the docs:

Note: useCapture has not always been optional. Ideally, you should include it for the widest possible browser compatibility.

So yes, you should set it to false to support a vast diversity of clients.

Also, you need to know when you might want to set it to true. Let's say you are listening for blur event on a single input textbox, then you can keep it as false like:

const blog = document.querySelector('#blog');
blog.addEventListener('blur', function (event) {
// Your logic here...
}, false);

But, if you want to listen to all blur events in the document, then you should set it to true like:

document.addEventListener('blur', function (event) {
// Your logic here...
}, true);

As, setting it to true help us to take advantage of event bubbling for events that otherwise don't support it like focus, blur, etc. Basically it is false for most used events, thus this param is optional in modern browsers and its defaults to false.

Why is 'false' used after this simple addEventListener function?

I checked MDN too, but I still didn't understand what the useCapture was for, so this answer is for those who still don't get it after having checked the official documentation.

So first of all, the following happens in almost all browers:

In all browsers, except IE<9, there are two stages of event processing.

The event first goes down - that’s called capturing, and then bubbles up . This behavior is standartized in W3C specification.

which means no matter what you set the useCapture to, these two event phases always exist.

This picture shows how it works.

Sample Image

According to this model, the event:

Captures down - through 1 -> 2 -> 3.

Bubbles up - through 3 -> 2 -> 1.

Then comes your question. The 3rd param called useCapture indicates on which of the two phases you want your handler to handle the event.

useCapture = true

The handler is set on the capturing phase. Events will get to it before getting to its children.

useCapture = false.

The handler is set on the bubbling phase. Events will get to it after getting to its children.

which means that if you write code like this:

child.addEventListener("click", second);
parent.addEventListener("click", first, true);

when clicking child element, first method will be called before second.

By default, the useCapture flag is set to false which means you handler will only be called during event bubbling phase.

For detailed info, click this reference link and this.

Passing parameters in addEventListener

When the browser calls the event handler, this will refer to the element, not your instance.

You need to save a copy of the desired this in a separate variable:

var self = this;

var func = function(e) { self.onTitleChange (e); };
var target = content.document.getElementsByTagName('TITLE')[0];
target.addEventListener('DOMSubtreeModified', func, false);


Related Topics



Leave a reply



Submit