I have a table row in which there is an element with an event handler delegated to document element, and the row itself also has another handler delegated to the tbody element. Codes like below:
// first part is defined in an initiating script file, so no jQuery used.
document.addEventListener('click', function(e) {
var el = e.srcElement || e.target;
if (el && el.classList && el.classList.contains('gotocontact')) {
e.stopPropagation();
alert('going to contact...')
}
})
// second part is defined after the jQuery included...
$('#list').on('click', 'tr', function() {alert('click tr...')})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.0/jquery.min.js"></script>
<table class="table">
<tbody id="list">
<tr>
<td><a class="gotocontact">John Doe</a></td>
<td>Male</td>
</tr>
<tr>
<td><a class="gotocontact">Jane Doe</a></td>
<td>Female</td>
</tr>
</tbody>
</table>
I put the stopPropagation there but it doesn't work as I expected: when I click the a element, the tr handler should not be triggered. Anyone can provide some hints?
If you want to prevent the jQuery listener from triggering, you should call stopPropagation
in the capturing phase rather than in the bubbling phase, by passing a third true
argument to addEventListener
:
document.addEventListener('click', function(e) {
var el = e.srcElement || e.target;
if (el && el.classList && el.classList.contains('gotocontact')) {
e.stopPropagation();
alert('going to contact...')
}
}, true)
// ^^^^ add third parameter
$('#list').on('click', 'tr', function() {alert('click tr...')})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.0/jquery.min.js"></script>
<table class="table">
<tbody id="list">
<tr>
<td><a class="gotocontact">John Doe</a></td>
<td>Male</td>
</tr>
<tr>
<td><a class="gotocontact">Jane Doe</a></td>
<td>Female</td>
</tr>
</tbody>
</table>