2

I had a "Sign Out" button on one of the pages of my website, but for some reason, whenever I clicked it, the Jquery function that was supposed to be triggered never was triggered. The button worked on other pages of my website, and I spent a while trying to figure out the issue.

Here's my Jquery code:

$(document).ready(function(){
    $("#signOut").on("click", function(){
        signout(); 
    });
});

After a bit of debugging, I realized that if I did $("signOut").trigger("click") in the console, the sign out worked perfectly. The css hover and active were working on the button, so I was extremely confused. Then I found this Jquery button click() function is not working and the solution worked for me. I changed my code to

$("document").on('click', '#signOut', function () {}

and it worked... but my button wasn't dynamically created.

Eventually, I realized that I had duplicated the html code. I had my button created before my php and after my php code (that's why I didn't see it). After I got rid of the duplication, my old code worked well, but I'm still confused as to why it created all these problems and why the dynamically created button solution worked.

Bob
  • 33
  • 4

1 Answers1

1

You are seeing the mentioned behavior as there are some differences between click() and on() depending on at which level the handler is associated.

Explanation

  • click() handler is associated by jQuery with the DOM element having the matched ID. In case you have duplicate IDs, jQuery gets the first DOM element (since ID is needed to be unique) and associates with the handler, rest elements are skipped. Now, when the second or third element is clicked, surely the event is generated but, propagated to the parent elements directly as there is no handler associated with the clicked DOM element.

  • click() handler association has no effect in case the DOM element is added dynamically at later point of time. This is not your scenario but just for your information.

  • on() handler (click event) associated with the parent element of DOM elements having duplicate ID gets the event as described above (the event is propagated to parent elements). It then matches by specified ID irrespective of duplications and executes the handler.

  • Similarly, click() handler associated with the parent element of DOM elements having duplicate ID gets the event as described above and executes the handler.

The above explanation is true not only for click event but, applicable to other event types as well.

Recommendations

  • Avoid using duplicate IDs in a page. If you still have some sort of duplications, go for class and associate handler by class. Otherwise, associate the handler to a parent element and match children by ID, class, element name, etc.

  • If you dynamically create DOM elements, go for handler association with the parent element and match children by ID, class, element name, etc.

Example

In the below example:

  • When Button 1 is clicked you see logs from 3 places: button specific handler, parent specific handler, and parent general handler
  • When Button 2 is clicked you see logs from only 2 places: parent specific handler and parent general handler.

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="utf-8">
    <title>Click Events</title>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
    <script>
        $(document).ready(function () {
            $("#b1").click(function () {
                console.log("From specific handler: " + this.innerHTML);
            });
            $("#p").on("click", "#b1", function () {
                console.log("From parent specific(b1) handler: " + this.innerHTML)
            });
            $("#p").click(function () {
                console.log("From parent general handler: " + this.innerHTML)
            });
        });
    </script>
</head>

<body>
    <div id="p">
        <button id="b1">Button 1</button>
        <button id="b1">Button 2</button>
    </div>
</body>
fiveelements
  • 3,649
  • 1
  • 17
  • 16