0

I have an event "pointerdown" but I want it to cancel the event call when a certain condition is met in one of the callbacks. So, all the next callbacks should not be called.

I have tried evt.preventDefault(); but that does not work, I have also tried evt.stopPropagation(); but that does not work.

const pointer = getMousePos(evt);
if (inBounds(pointer)) {
    evt.preventDefault();
    evt.stopPropagation();
}

The inBounds function returns true as expected, but the next callbacks of the event are still called. This event is added first, before the other events I wish to cancel but they are not.

Ripper
  • 97
  • 8
  • `stopPropagation` is to prevent the current event from bubbling to outer elements in the DOM. `preventDefault()` prevents the normal action of the event (e.g. clicking on a submit button submits the form). Neither of them has anything to do with later events. – Barmar Jun 20 '19 at 02:45
  • Is there any event that allows me to stop calling the later events? Or am I going to have to code that myself? – Ripper Jun 20 '19 at 02:46
  • What do you mean by later events? It's not clear what you're really trying to do. You can set a global variable, and check it in the event listener. If the variable is set, just return from the listener function instead of doing something. – Barmar Jun 20 '19 at 02:47
  • Like, if I add function A into "pointerdown" event. And then I add a function B into "pointerdown" event. I want to call something in function A, to stop it from calling all of the next functions, which would include function B. – Ripper Jun 20 '19 at 02:49
  • Try to set the useCapture (the third parameter) to true to see if it would help. – Pinetree Jun 20 '19 at 02:58
  • I did. Nothing changed :( – Ripper Jun 20 '19 at 03:00

2 Answers2

1

If your listeners are attached on the same element, you will need to use stopImmediatePropagation() instead of stopPropagation()

The stopImmediatePropagation() method of the Event interface prevents other listeners of the same event from being called.

If several listeners are attached to the same element for the same event type, they are called in the order in which they were added. If stopImmediatePropagation() is invoked during one such call, no remaining listeners will be called.

https://developer.mozilla.org/en-US/docs/Web/API/Event/stopImmediatePropagation

You can also find a little description of the difference between both methods here: stopPropagation vs. stopImmediatePropagation

Here a little demonstration of how you can use it. In this case, the second listener will never be called when the counter is a even number.

let counter = 0

const button = document.getElementById('TheButton')

button.addEventListener('click', e => {
  counter++
  
  console.log(`first listener: ${counter}`)
  
  if (counter % 2 === 0) e.stopImmediatePropagation()
})

button.addEventListener('click', e => {
  console.log(`second listener: ${counter}`)
})
<button id="TheButton">
OK
</button>
Community
  • 1
  • 1
EmeraldCoder
  • 527
  • 3
  • 12
0

Use a global variable that you toggle to indicate whether the other event code should run.

let doBFunction = true;
element.addEventListener("pointerdown", function(evt) {
    const pointer = getMousePos(evt);
    if (inBounds(pointer)) {
        doBFunction = false;
    } else {
        doBFunction = true;
    }
    // rest of code
});
element.addEventListner("pointerdown", function(evt) {
    if (!doBfunction) {
        return;
    }
    // rest of code
});

Barmar
  • 741,623
  • 53
  • 500
  • 612