5

I've made this test code for the question: https://jsfiddle.net/5phqm/1/

As far as I understand, if jQuery's triggerHandler() prevents default browser behavior, then native JavaScript events will not be triggered and handled (and it's true for addEventListener() in my code), but inline event, added through tag's attribute onclick="" will be triggered anyway! Why it happens? Am I misunderstanding something about events triggering in browser?

Syscall
  • 19,327
  • 10
  • 37
  • 52
Raiden
  • 135
  • 1
  • 6
  • For what it's worth I always think of this as following the CSS rules pattern of behaviour: the in-line code overrides the code found in the `head` which in turn overrides the code found in an external script. You could simply `removeAttr('onclick')`. – David Thomas Nov 30 '11 at 11:48
  • 2
    This is not a direct answer but at the jQuery website they state they do not spend effort on issues with inline event handlers: http://docs.jquery.com/Won't_Fix#Inline_Event_Handlers. I'd be interested to know why your code behaves as it does, but I don't think there will be a fix for it (in case you find it a bug). – pimvdb Nov 30 '11 at 11:52

2 Answers2

2

It can be confirmed that inline handlers are run because it is explicitly coded:

handle = ontype && cur[ ontype ];
if ( handle && jQuery.acceptData( cur ) && handle.apply( cur, data ) === false ) {
    event.preventDefault();
}

where ontype is in this case "onclick". So it is fetching the onclick property of the element and then executing it. This piece of code is always called, regardless of .trigger/.triggerHandler.

Native actions however, like elem.click(), are only executed inside an if block:

if ( !onlyHandlers && !event.isDefaultPrevented() ) {
    // ...
    elem[ type ]();

where onlyHandlers is true for triggerHandle and false for .trigger, and therefore triggerHandler does not execute e.g. elem.click() (whereas .trigger does). As such, the native action is prevented.

So inline handlers and native actions are separate things and are also handled separately. Only native actions are prevented by .triggerHandler.

pimvdb
  • 151,816
  • 78
  • 307
  • 352
0

I think (but it's a guess, i gave a brief look at jQuery source code and this might be totally wrong) that jQuery retrieves the events attached to elements in jQuery.trigger.event by calling something like

   $(elem).data("events");

and then decides if to fire/stop them. Inline events can't be collected this way and so they can't be stopped.

Nicola Peluchetti
  • 76,206
  • 31
  • 145
  • 192