Inverse popup event in javascript

As you know, events usually appear in javascript, so the event handler that fires the event is executed first, then the parent's event handler is called, and so on. This behavior causes some problems in the project I'm working on now, I would prefer to change the order of execution.

I calculated a solution using timeouts:

$(element).mouseover(function(){ var that = this; setTimeout(function() { //actual event handler, but references to "this" are replaced with "that" },$(this).parents().length) }); 

So, basically, event handlers are executed after a short timeout, the wait time depends on the depth of the element in the DOM tree: the event handler of the html element is executed immediately, the event handler of the body element is executed after 1 ms, etc. Thus, the execution order of events is canceled.

The results of my first tests are positive, but I'm still not sure if there are any problems or flaws with this solution. What do you think of this decision? Other ideas on how to solve these problems are also much appreciated.

+7
source share
3 answers

The reverse event bubble is called the capture phase.

See DOM Event Architecture

Pass true as the third argument to Event.addEventListener so that it Event.addEventListener at the capture stage

 el.addEventListener("click", function () { console.log("i run in capture"); }, true); 

Of course, it will not work on legacy platforms. To emulate an event system, you need the DOM3 event jumper. Feel free to contribute to DOM-shim

+14
source

I see one huge drawback of your solution - the fact that for each event handled you need to go up the DOM, starting with this , to set the number of parents.

Moving this way in each event handler = low performance.

0
source

You might try to imitate him, but this can probably cause a ton of problems.

Here is a very simple example (and on jsfiddle ). The idea is to aggregate callbacks from each event and call them in reverse order in the document event handler (we also clear our list to provide a new queue the next time it is clicked).

 <div id="a"> <div id="b"> <a href="/test">Click Me!</a> </div> </div> 
 var cb = []; $(document).click(function(evt){ cb.unshift(function(){ console.log('document'); }); var i; for(i=0; i<cb.length; ++i){ cb[i].call(null, evt); } cb = []; }); $("#a").click(function(){ cb.unshift(function(){ console.log('div#a'); }); }); $("#b").click(function(){ cb.unshift(function(){ console.log('div#b'); }); }); $('a').click(function(evt){ cb.unshift(function(evt){ evt.preventDefault(); console.log('a'); }); }); 

Maybe you need to change your design? Could you post more information, why do you need event capture?

0
source

All Articles