I'm wondering why a addEventListener("click", function(){})
is not called when triggered by a jQuery .trigger("click")
but it IS called when triggered by a dispatchEvent(new Event("click"))
.
var el = document.getElementById("foo");
$(el).click(function() { console.log("jquery click"); });
el.onclick = function() { console.log("onclick"); };
el.addEventListener("click", function() { console.log("addEventlistener click"); });
$(el).trigger("click");
console.log("--------");
el.dispatchEvent(new Event("click"));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a href="#foo" id="foo">foo</a>
This produces the following console output
(index):54 jquery click
(index):55 onclick
(index):59 --------
(index):54 jquery click
(index):55 onclick
(index):56 addEventlistener click
Am I missing something? Does jQuery "fake" a click by calling it's event listeners directly?
jQuery's trigger
fires the jQuery handlers and calls the .event()
function on the element* — unless it's a click
on an a
element, in which case it doesn't do that second part. (It also treats checkboxes specially.) E.g., we see it if we use a div
in your example:
var el = document.getElementById("foo");
$(el).click(function() { console.log("jquery click"); });
el.onclick = function() { console.log("onclick"); };
el.addEventListener("click", function() { console.log("addEventlistener click"); });
$(el).trigger("click");
console.log("--------");
el.dispatchEvent(new Event("click"));
<div id="foo"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
...but not on your a
:
var el = document.getElementById("foo");
$(el).click(function() { console.log("jquery click"); });
el.onclick = function() { console.log("onclick"); };
el.addEventListener("click", function() { console.log("addEventlistener click"); });
$(el).trigger("click");
console.log("--------");
el.dispatchEvent(new Event("click"));
<a href="#foo" id="foo">foo</a>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
Why not? For "cross-browser consistency" the source says: See https://github.com/jquery/jquery/blob/master/src/event.js#L476 (that link is to a line number, and so may will rot):
click: {
// For checkbox, fire native event so checked state will be right
trigger: function() {
if ( this.type === "checkbox" && this.click && nodeName( this, "input" ) ) {
this.click();
return false;
}
},
// For cross-browser consistency, don't fire native .click() on links
_default: function( event ) {
return nodeName( event.target, "a" );
}
},
Note that bit at the end.
* This is a bit tricky to find. trigger
says:
Any event handlers attached with
.on()
or one of its shortcut methods are triggered when the corresponding event occurs. They can be fired manually, however, with the.trigger()
method.
...but triggerHandler
says:
The behavior of this method is similar to
.trigger()
, with the following exceptions:
.triggerHandler( "event" )
method will not call .event()
on the element it is triggered on. This means .triggerHandler( "submit" )
on a form will not call .submit()
on the form..trigger()
will operate on all elements matched by the jQuery object, .triggerHandler()
only affects the first matched element..triggerHandler()
do not bubble up the DOM hierarchy; if they are not handled by the target element directly, they do nothing..triggerHandler()
returns whatever value was returned by the last handler it caused to be executed. If no handlers are triggered, it returns undefinedCould definitely be clearer on this point.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With