简体   繁体   中英

jQuery .click() trigger event on non-existent html element

I have an HTML button with an ID of "open". I have added a jQuery .click() binding to the HTML button which is selected by ID. In the .click() binding I change the ID of "open" to "close". However, subsequent clicks on the "open" button are still firing even though the ID has been changed to "close". The code is as follows:

index.html

<!DOCTYPE html>
<html>
<head>
    <title></title>
</head>
<body>
    <button id="open">Open</button>

    <script type="text/javascript" src="js/jquery-1.11.3.min.js"></script>
    <script type="text/javascript" src="js/index.js"></script>
</body>
</html>

index.js

$('#open').click(function() {
    console.log("clicked");
    $(this).attr('id', 'close');
});

https://jsfiddle.net/iHexBot/28tj1ywg/

I was expecting / hoping to see the console log "clicked" only one time. However, it logs "clicked" every time the button is clicked even though the HTML elements ID is no longer "open". Could someone please explain to me why this happens and if possible, how to fix this?

If you only want to trigger once I would try this:

$('#open').one("click", function() {
    console.log("clicked");
    $(this).attr('id', 'close');
});

but if you are creating a 'toggle' button I wouldn't do it this way. I would create one event that will act differently depending on whether it should be opening or closing, as other answer here suggest.

You can bind the event to document instead of the element like so

$(document).on('click', '#open', function() {
    console.log('this will only be displayed as long as id is "open"');
});

Use this script instead:

$('#open').bind('click', function() {
    console.log("clicked");
    $(this).attr('id', 'close').unbind('click');
});

Here is the code to toggle between open and close

<button class="toggleButton" data-option="open">Open</button>

$(document).on('click','.toggleButton',function() {
 if($(this).attr('data-option') == 'open') {
  console.log('open');
  // do something if "open" clicked;
  $(this).text('Close');
  $(this).attr('data-option','close');
 }else{
  console.log('close');
  // do something if "close" clicked;
  $(this).text('Open');
  $(this).attr('data-option','open');    
 }
});

jsfiddle - https://jsfiddle.net/ygf1327m/

For this purpose you "should" use ONE() rather than to unbind. Just to demonstrate this I have edited your original JSFIDDLE.

   jQuery(document).ready(function ($) 
    {  
    //the element to evaluate
     var current_id= $("button#open");
     alert("The ID of the button is: " + current_id.attr("id") );
     current_id.one("click", function () {  
     //now once we click the button we have
     current_id.attr('id', 'close');
     alert("Now the ID is: " + current_id.attr('id') + "  so we are changing it\'s text too...  "  );
     //reflect the change
     current_id.text("Close");     
     });
    });

JSFIDDLE:
https://jsfiddle.net/28tj1ywg/4/

jQuery will bind a .click() event on the browser load instead of re-binding it after each click.

You're going to want to .unbind() this event which should sort your issue out.

 $('#open').click(function() { console.log("clicked"); $(this).attr('id', 'close'); $(this).unbind(); }); 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <button id="open">Open</button> 

The reason is that while executing the event handler its context (ie 'this' object) is different to the defining context. See also How do I pass the this context into an event handler?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM