简体   繁体   中英

jquery event firing twice on single click

I am working with a web application where I am re-ordering HTML table rows and am seeing when an item with a class is clicked. The event is firing twice but I do not see how.

I would be grateful if anyone would be able to let me know how I can stop this behavior as this will be creating an AJAX call and passing the array back to the code behind but I only need and want it to fire once.

 $('table').on('click', ".up,.down,.top,.bottom", function() { console.log("up or down arrow clicked"); var row = $(this).parents("tr:first"); if ($(this).is(".up")) { if (row[0].rowIndex > 1) { row.insertBefore(row.prev()); } } else if ($(this).is(".down")) { row.insertAfter(row.next()); } else if ($(this).is(".top")) { row.insertBefore($("table tr:first")); row.insertAfter(row.next()); } else { row.insertAfter($("table tr:last")); } //... more code here }); 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" /> <table> <tr id="sectionRow_1010_M_TR" style="border: 1px solid black;"> <td style="padding: 0px; width: 15px;"> <input class="collapse" id="btnMinus0_1010" style="padding: 0px; width: 15px; height: 20px; text-align: center; vertical-align: top; display: none;" onclick="collapse('0_1010')" type="button" value="-"> <input class="expand" id="btnPlus0_1010" style="padding: 0px; width: 15px; height: 20px; text-align: center; vertical-align: top;" onclick="expand('0_1010')" type="button" value="+"> </td> <td style="padding: 0px; width: 100%; text-align: left; background-color: gray;"> <span>Engine, Fuel and Cooling Systems</span> </td> <td> <a class="up" href="#"><i class="fa fa-angle-up" aria-hidden="true"></i></a> <a class="down" href="#"><i class="fa fa-angle-down" aria-hidden="true"></i></a> </td> </tr> </table> 

Your symptom doesn't match your code, but the three most likely reasons for your symptom are (I lean toward #3):

  1. You have an .up , .down , .bottom , or .top element inside an .up , .down , .bottom , or .top element. So since click propagates (and jQuery faithfully replicates that when doing event delegation), it's firing for the innermost match, and also for the outermost match.

    If so, target the handler more directly at the elements in question.

    or

  2. You're running your code twice, and thus setting up two handlers, each of which is firing.

    If so, er, don't do that. :-)

    or

  3. Your table is inside another table , so $("table") matches both of them, and again because click propagates (at the DOM level this time), you get a response from both tables.

    If so, target just the table you want these handlers hooked up in.

Since your code doesn't replicate it, here's a simplified example of #1:

 $("table").on("click", ".up, .down", function() { console.log(this.className + " clicked"); }); 
 <table> <tbody> <tr class="up"> <td class="down">Click me</td> </tr> </tbody> </table> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 

...and of #2:

 $(document).ready(setup); $(window).load(setup); function setup() { $("table").on("click", ".up, .down", function() { console.log(this.className + " clicked"); }); } 
 <table> <tbody> <tr> <td class="down">Click me</td> </tr> </tbody> </table> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 

...and of #3:

 $("table").on("click", ".up, .down", function() { console.log(this.className + " clicked"); }); 
 <table> <tbody> <tr> <td> <table> <tbody> <tr> <td class="down">Click me</td> </tr> </tbody> </table> </td> </tr> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 

1) It may be happening as you are assigning the same handler to click event multiple times. I suggest, you kindly check the line where you assign the handler. I guess it is being called multiple times. A solution could be a call to unbind first then bind, like this:

$('table').unbind("click").click('.up,.down,.top,.bottom') {
     //Do Stuff
});

$('table').off("click").on('click', ".up,.down,.top,.bottom", function() {
     //Do Stuff
});

2) if in any case, if you find that .off() .unbind() or .stopPropagation() can't fix your issue, please use .stopImmediatePropagation() . It usually works great in these kind of situations when you just want your event to be handled without any bubbling and without effecting any other events already being handled. Something like:

$("table").click(function(event) {
  event.stopImmediatePropagation();
  //Do Stuff
});

which does the trick always!

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