1

I'm currently working on a chrome extension where I need to prevent a default click action on any page the extension is loaded on. Normally I would just do something like the below to prevent a default action:

$('.some-element').click(function(e){
 e.preventDefault()

// some other code

});

I'm using the same approach here with my extension but what i'm finding is that sometimes this will work and other times not. For example if I go to a site where an <a> tag in an area of the page has already had a preventDefault bound to it then the preventDefault of that website will prevent my event from running..

How does the hierarchy of the click events work - is it that the first function that was loaded in will always fire first? If so is there a way I can impose a hierarchy on events so that my event will always fire first therefore preventing any other actions loaded on the page?

The action that already exists on the page needs to only be temporarily disabled so an approach where I completely unbind all events might not be suitable if I can't bind them again..

Thanks

red house 87
  • 1,837
  • 9
  • 50
  • 99
  • Are you saying you're injecting JavaScript code to listen to click events I'm assuming in the developer console of chrome for other people's websites? I'm confused how you mentioned both your website and other websites. If you're trying to do what I think you're trying to do, I don't think it's going to work. – Chris Hawkes Aug 16 '17 at 21:01
  • Basically im trying to prevent any default onClick event from firing on a website via the code I inject onto a page through my content script. From there I want to use my own functions to do several things. So far it works but like I said if there is already an event.preventDefault set on an element on a website then THAT event.peventDefault will fire as opposed to my event.preventDefault that I have injected to the page via my content script. I don't think I mention my website once... it's a chrome extension – red house 87 Aug 16 '17 at 21:14
  • 1
    Attach a mousedown listener on window, the topmost DOM object, and specify true for the useCapture parameter of addEventListener to intercept the event at the very start of the capturing phase from window to the click target. This code will run before the target's mousedown. And if you do it in a content script that runs on document_start, no page will be able to supersede that. – wOxxOm Aug 16 '17 at 21:32
  • This makes complete sense, will try it tomorrow morning and let you know if it works. Thanks! – red house 87 Aug 16 '17 at 21:34
  • 1
    Related (some explanation): [How to ONLY trigger parent click event when a child is clicked](https://stackoverflow.com/a/38861760) – Makyen Aug 17 '17 at 21:28

1 Answers1

1

Please note, that normal event listeners (Element.addEventListener) and jQuery .click/.on are two different things. jQuery sets listener once, and has its internal array of callbacks.

If you want to prevent all certain type of listeners from firing, add listener to window using capturing mode (3rd argument):

window.addEventListener('mousedown', (e) => {
  e.preventDefault()
}, true);
Artur
  • 628
  • 6
  • 14
  • Ok, would you say combining this with wOxxOm's suggestions: using the mousedown event listener instead of click and adding the event listener to window instead of body would add more certainty to the code above? – red house 87 Aug 16 '17 at 21:42
  • @BenLiger Yes, sure. Done. – Artur Aug 16 '17 at 21:49
  • Almost there... After amending my code my event now fires on sites where it previously didn't. The only issue now is that MY prevent default does not seem to work ie the other functions on the pages are still firing in parallel with mine.. – red house 87 Aug 17 '17 at 08:47
  • 1
    @BenLiger, That's because you are confused between the effects of [`Event.preventDefault()`](https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault), [`Event.stopPropagation()`](https://developer.mozilla.org/en-US/docs/Web/API/Event/stopPropagation) and [`Event.stopImmediatePropagation()`](https://developer.mozilla.org/en-US/docs/Web/API/Event/stopImmediatePropagation). Note also that your script needs to run a `document_start` if you want to be sure your event handler runs prior to in-page handlers. – Makyen Aug 17 '17 at 21:27