I am having issues with my click events due to nested elements and the nature of what I am trying to accomplish.
When I click on the .main
, the selected
class is added. However when I click on .close
, the selected
class is removed and then added back again. Is there anyway to get around this?
The reason why I have it setup this way is because I want to maximize my clickable area (the entire element).
$('.main').off('click.a').on('click.a', function() {
$('.child2', $(this)).addClass('selected');
});
$('.close').off('click.B').on('click.B', function() {
$(this).parent().removeClass('selected')
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>
<div >
<div>some content</div>
<div >
<span >X</span>
</div>
</div>
CodePudding user response:
The issue is because the .close
element is a child of the .main
. This means that the event fires on .close
, and the class is removed. The event then propagates up the DOM to the .main
element where it's caught by the other event handler and the class gets added on again.
To prevent the event from propagating up the DOM, call stopPropagation()
on it from within the .close
click handler:
$('.main').off('click.a').on('click.a', function() {
$(this).find('.child2').addClass('selected');
});
$('.close').off('click.B').on('click.B', function(e) {
e.stopPropagation();
$(this).parent().removeClass('selected')
});
.selected { color: #C00; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>
<div >
<div>some content</div>
<div >
<span >X</span>
</div>
</div>
As a side note, using .off('event').on('event', fn)
is a code smell. You may be better off using a single delegated event handler which you can bind only once when the page loads. It would depend on your exact use case, though.