Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript pause event propagation

I need to be able to chain click events, and temporarily pause event propagation between them.

So, for a given element, it runs three different click events, but the second one needs user input, so it pauses propagation while the user fills in the form and then continues.

clickAction2 = ->
  #Pause event propagation
  somehow.pauseEventPropegationRightHere()

  #Go and handle the dialogs, user input, JS requests
  goDoSomething().thenDoCallback( ->
     #User is now authenticated completely.
     somehow.continueEventPropegationAsIfNothingHappened()
  )

In an effort to allow single responsibility, and events chained higher/lower shouldn't have knowledge that the event propagation was paused and nothing should be called twice.

No, the three click events can't be called sequentially from another function or any similar primitive solution.

This is in relation to AngularJS directives, but the solution does not need to rely on it.

There is a similar question but none of the answers are satisfactory: How to continue event propagation after cancelling?.

Edit:

What I need is a cleaner way to call e.stopImmediatePropagation(), and then continue from that point. As of right now, my best option is by manually entering the jQuery "private' data[1] and calling the functions manually.

  1. $._data( $(element)[0], 'events' ).click[].handler()
like image 255
Aaron Harun Avatar asked Jan 10 '14 12:01

Aaron Harun


People also ask

How do you stop event propagation?

To stop an event from further propagation in the capturing and bubbling phases, you call the Event. stopPropation() method in the event handler. Note that the event. stopPropagation() method doesn't stop any default behaviors of the element e.g., link click, checkbox checked.

How do you stop event propagation in typescript?

Try with (click)="$event. stopPropagation()" .

Which event can be used to stop event propagation in react?

stopPropagation() will stop event from propagating to the window.


1 Answers

I had a similar issue myself and I hope my solution is satisfactory because I realize it may not directly apply to your situation. However hopefully the principle I show here helps you find a solution of your own.

The problem (if I understand correctly) is that you need a way to prevent a child element from triggering an event if a parent element has triggered the same event at essentially the same time. Whereas e.stopImmediatePropagation() prevents event bubbling, effectively halting any parent elements from triggering the event. I believe the solution is using a setTimeout() with a zero millisecond delay to perform the desired function and if the triggering event ever occurs again while the setTimeout() is in use, use clearTimeout() to stop the previous event from occuring. The best way I can demonstrate this approach is by creating a parent and child element and watching the mouseleave event.

Here is the JS/jQuery:

var timerActive = false;
$('#div1, #div2').mouseleave(function(e) {
    var trigger = $(this).attr('id'); // for monitoring which element triggered the event
    if (timerActive) {
        clearTimeout(announce); // stops the previous event from performing the function
    }
    window.announce = setTimeout(function() {
        alert('mouse exited'+trigger); // trigger could be use in an if/else to perform unique tasks
        timerActive = false;
    },0);
    timerActive = true;
});

Here is a JSFiddle demo: http://jsfiddle.net/XsLWE/

Since the events are triggered sequentially from child to parent, clearing each previous timeout effectively waits for the last or top-most element to trigger the event. At which point you could use an IF/ELSE statement to perform desired tasks. Or perform one function then a callback on complete.

In the demo, the effect is that on the left and bottom edges of the div elements, each div element is allowed to trigger the event individually. However on the top and right edges of div2, the only element allowed to trigger the event is div1.

Again, from your original post, I take it you are after something slightly different. But perhaps this approach will help you in some way.

like image 133
user3207952 Avatar answered Oct 12 '22 00:10

user3207952