0

I create a button within the <td> tag of a HTML table.

I've added a listener to trigger an alert on click event.

The <td> tag of the HTML table is equally tight to an event listener and triggers an alert with a distinct text from the button on click.

The snippet below illustrates the scenario above.

$("#mytable").on("click", "td", function() {
    alert('this is td');
});  
   
$("#mybutton").on("click", function() {
    alert('this is button');
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.0/jquery.min.js"></script>
<table id="mytable">
    <tr>
        <td style="border: 1px solid black; width: 500px; height: 20px">
            <span>table</span>
            <button style="margin: 5px; padding:5px; border: 1px solid black; float: right" id="mybutton"> display</button>
        </td>
    </tr>
</table>

How can I effectively make the click event on the button execute without triggering the click event of the <td> tag in which the button is enclosed?

nyedidikeke
  • 6,899
  • 7
  • 44
  • 59
daniel8x
  • 990
  • 4
  • 16
  • 34

2 Answers2

2

You have to stop the propagation of the click event after it has been consumed by a click on your button. This is done by a call to the stopPropagation() function on the event. Otherwise - as you experienced - the event will be propagated to the next element.

Here's an example:

 $("#mytable").on("click", "td", function() {
     alert('this is td');
   });
   
   
 $("#mybutton").on("click", function(event) {
   event.stopPropagation();
     alert('this is button');
   });
   
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.0/jquery.min.js"></script>
<table id="mytable">
<tr>
  <td style="border: 1px solid black; width: 500px; height: 20px">test
  <button style="margin: 5px; padding:5px; border: 1px solid black; float: right" id="mybutton"> display</button>
  </td>
</tr>
</table>
obscure
  • 11,916
  • 2
  • 17
  • 36
  • 1
    @daniel8x Using this approach, you may find some of the answers to [this question](https://stackoverflow.com/q/5963669/4342563) very useful. – Eric Lease May 14 '19 at 21:32
-1

For the record, I prefer obscure's approach, if possible. However, that will prevent all further events that would have been triggered by the click. If there are multiple events attached to the click, and you only want to target a specific one to be ignored you may want a scheme something like the following...

(function($){
    // creating variables for the event handlers, for cleaner code below
    let tdEvtHandler = function() {
     alert('this is td');
   };

   let bindTd= function() {
     $("#mytable").on("click", "td", tdEvtHandler);
   };

   let btnEvtHandler = function() {
     // The button's evt handler will take precedence when
     // the button is clicked, so you can disable just the
     // td's evt handler at this point, do your work, then
     // re-enable the td's evt handler.  Re-binding needs to
     // be done with a timeout to allow the current event
     // chain to complete before (re)binding takes place.

     $("#mytable").off("click", "td", tdEvtHandler);
     alert('this is button');
     setTimeout(bindTd);
   };

   bindTd();
   $("#mybutton").on("click", btnEvtHandler);
})(jQuery);
Eric Lease
  • 4,114
  • 1
  • 29
  • 45