The issue is that the click
is propagating to the delegated click handler, and by the time the click reaches the delegated handler, the button already has the class, so the delegated handler fires.
Just top the click propagation, so it doesn't reach the delegated handler, but adding either return false
at the end or e.stopPropagation()
to your first click` handler. You need to not do that if the button already has the class, so that you don't prevent the delegated handler from firing when it has the class already:
$('button').on('click', function(e){
var $this = $(this);
if (!$this.hasClass("added")) {
$this.addClass("added");
return false;
}
});
Live Example:
$('button').on('click', function(e){
var $this = $(this);
if (!$this.hasClass("added")) {
$this.addClass("added");
return false;
}
});
$(document).on('click', '.added', function(e){
e.preventDefault();
alert("Clicked on .added");
})
<div id="banner-message">
<p>On first click, add .added class to the button</p>
<p>On clicking .added, show alert</p>
<button>Click</button>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
In that example, I added return false;
at the end (and removed e.preventDefault()
), because a return false
out of a jQuery click handler both prevents the default and stops propagation.
Another approach would be to use two delegated handlers: One for when it doesn't have the class, another for when it does:
$(document).on('click', '.foo:not(.added)', function(e){
e.preventDefault();
$(this).addClass("added");
});
$(document).on('click', '.added', function(e){
e.preventDefault();
alert("Clicked on .added");
})
<div id="banner-message">
<p>On first click, add .added class to the button</p>
<p>On clicking .added, show alert</p>
<button class="foo">Click</button>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Note I added a class to the button so I could identify it for the first delegated handler.