While I am trying to learn jquery I learned that $(selector) returns an object which has all the match of that selector and is iterable like arrays. eg $("button")
will return an object that will have access to all the button tag of DOM in such way that to access the first button tag you can use $["button"][0]
for second you can use $["button"][1]
and so on.
So here below is code focus on commented line 1 and line 2.
<body>
<button>Click me</button>
<script>
$(document).ready(function() {
// line 1
$("button").click(function() {
console.log("1");
// line 2
$("button").click();
});
});
</script>
</body>
line 2 inside line1 event handler function is set up an infinite loop as you can see that when I Click on "Click me" button it will trigger line1 inside of which is line 2 which too will again trigger line 1 and so on. now see the below code snippet with changed line2.
<script>
$(document).ready(function() {
// line 1
$("button").click(function() {
console.log("1");
// line 2
$("button")[0].click();
});
});
</script>
This time it is not setting up an infinite loop but prints to console "1" only two times why so?
So onclick creates an attribute within the binded HTML tag, using a string which is linked to a function. Whereas . click binds the function itself to the property element.
jQuery click() MethodThe click event occurs when an element is clicked. The click() method triggers the click event, or attaches a function to run when a click event occurs.
Javascript has a built-in click() function that can perform a click in code.
It is most likely the way in which the synthetic event is being invoked by JQuery.
Here is the JQuery snippet for event dispatch.
dispatch: function( nativeEvent ) {
// Make a writable jQuery.Event from the native event object
var event = jQuery.event.fix( nativeEvent );
var i, j, ret, matched, handleObj, handlerQueue,
args = new Array( arguments.length ),
handlers = ( dataPriv.get( this, "events" ) || {} )[ event.type ] || [],
special = jQuery.event.special[ event.type ] || {};
// Use the fix-ed jQuery.Event rather than the (read-only) native event
args[ 0 ] = event;
for ( i = 1; i < arguments.length; i++ ) {
args[ i ] = arguments[ i ];
}
event.delegateTarget = this;
// Call the preDispatch hook for the mapped type, and let it bail if desired
if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
return;
}
// Determine handlers
handlerQueue = jQuery.event.handlers.call( this, event, handlers );
// Run delegates first; they may want to stop propagation beneath us
i = 0;
while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) {
event.currentTarget = matched.elem;
j = 0;
while ( ( handleObj = matched.handlers[ j++ ] ) &&
!event.isImmediatePropagationStopped() ) {
// If the event is namespaced, then each handler is only invoked if it is
// specially universal or its namespaces are a superset of the event's.
if ( !event.rnamespace || handleObj.namespace === false ||
event.rnamespace.test( handleObj.namespace ) ) {
event.handleObj = handleObj;
event.data = handleObj.data;
ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle ||
handleObj.handler ).apply( matched.elem, args );
if ( ret !== undefined ) {
if ( ( event.result = ret ) === false ) {
event.preventDefault();
event.stopPropagation();
}
}
}
}
}
// Call the postDispatch hook for the mapped type
if ( special.postDispatch ) {
special.postDispatch.call( this, event );
}
return event.result;
}
Reading the spec for synthetic and authentic click events:
When a user agent is to run post-click activation steps on an element, it must run the activation behavior defined for that element, if any. Activation behaviors can refer to the click event that was fired by the steps above leading up to this point.
As JQuery has implemented a custom dispatch handler for emulating click events it looks like they have added the following in order to emulate that aforementioned native html event lifecycle.
if ( special.postDispatch ) {
special.postDispatch.call( this, event );
}
This call here is likely the suspect, proven when you look at the console output for the following. Note that you never see the console.log Done because the dispatch handler is never actually returning the event to complete it's native lifecycle (endless recursion), which I suspect is just frankly handled better by the native html implementation.
Infinite loop warning
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.0/jquery.min.js"></script>
<body>
<button>Click me</button>
<script>
$(document).ready(function() {
// line 1
$("button").click(function() {
console.log("start");
// line 2
$("button").click();
console.log("Done");
});
});
</script>
</body>
Good find!
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