Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

I am having a problem understanding the different behavior of $("button").click() and $("button")[0].click()

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?

like image 301
Yogesh_Singh Avatar asked Jun 24 '19 05:06

Yogesh_Singh


People also ask

What is difference between click and Onclick in jQuery?

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.

What is click function in jQuery?

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.

Can we click button using JavaScript?

Javascript has a built-in click() function that can perform a click in code.


1 Answers

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!

like image 161
Zze Avatar answered Oct 05 '22 09:10

Zze