Default Event Handling Detection

Is it possible to determine whether any specific DOM event is associated with any event handler (including the default browser event handling) - in Firefox Greasemonkey code ( EcmaScript 5.1 strict mode )?

So far, I have been able to cancel the processing of click events when selecting text, but I would like to cancel the processing of events in all of the following situations when the click event triggers a default action:

  • selection of text on the page Displays a context menu
  • (i.e. right click)
  • the link is executed (left-click on <a> ) Form elements
  • are processed (the text field receives focus, the cursor starts blinking, the radio button is selected, ...)
  • any other JavaScript code that processes the event (for example, a pop-up help dialog box is displayed)

Is there a catch-all mechanism for this, or do I need to explicitly specify all situations in my code?

The following code is how I found that the selection occurred:

 var toggleHighlight = function(){ var oldTargt; return function(e){ targt = e.target; sel = window.getSelection(); if (!sel.isCollapsed && sel.containsNode(targt, true)) { return; } ... oldTargt = targt; }() document.addEventListener('click', toggleHighlight); 

<sub> Notes:
- I do not want to stop the distribution using a script, I want to stop MY SCRIPT if the event is passed to another handler.
“I'm not interested in jQuery-events-handlers-only solutions unless they catch the default browser event handlers.”
- If this function really does not exist, quote some articles or blogs, and not just your own opinion.
- Special offers are welcome, but I am mainly interested in the existence of a common solution.

Update : acceptable solutions include:

  • an exhaustive (ish) list of if conditions that I need to check for
  • non javascript access from Firefox plugin
  • explanation of how Firefox knows that clicking on a valid <a> element should trigger a reload of the new URL +, as this logic is not available from javascript / plugins
+4
source share
1 answer

This question is almost a duplicate of "How to do an action only when there is no default value in Javascript / jQuery?" , except that as a Greasemonkey script, this is another (complex) option available to you.

From your question, it looks like you want to set a default action for nodes that don't have one, and then abort it by default if some other event handler fires for this event. There is no “retention mechanism” for this, and almost any technical attempt you are trying can cause a page to crash. That's why:

  • Neither javascript nor the Greasemonkey API provide any mechanism for listing events for a given node. There was an old proposal , but it was never implemented.

    However, Firefox add-ons can list events through nsIEventListenerService , so chances are you can write a helper add-on for this part that interacts with Greasemonkey. Details (path) are beyond the scope of this question.

  • Similarly, there is no mechanism for detecting previous events in the chain of events from an Event Object if event.defaultPrevented not set. (Usually this will not happen.)

  • Even if you can list event listeners for node X, this will not help deal with listeners on the parent nodes. Modern JS libraries can and sometimes make any old node clickable. And / or they can install a listener, say, a document , which receives all click events, but actually does nothing, except when the original target was a specific node.


A good compromise strategy is to follow this other question and do nothing for nodes with a default action.
To process right-clicks or center-clicks, click event.which .

Thus, you can add the following snippets to your checks:

 return function(e){ targt = e.target; sel = window.getSelection(); if (e.which != 1) { return; //-- Abort on anything that is not a left-click. } if (e.defaultPrevented) { return; //-- The one time we know that some other handler fired. } if (isInteractiveElement (targt) ) { // Do nothing for elements that trigger browser actions return; } ... 

Where:

 function isInteractiveElement (node) { var intElems = [ //-- Must be uppercase "A", "BUTTON", "INPUT", "TEXTAREA", "VIDEO", "MAP", "OBJECT" ]; if (intElems.indexOf (node.nodeName) >= 0) { return true; } else if (node.nodeName === "BODY") { return false; } return isInteractiveElement (node.parentNode); } 
+2
source

All Articles