2

I want to add a class to a button when clicking first time, and when clicking again on the newly added class, it should do something (for example show an alert).

I'm trying this, but this shows the alert on the first click, even though the class doesn't exist at first.

HTML:

<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>

jQuery

$('button').on('click', function(e){
    e.preventDefault();  
  $(this).addClass("added");
})

$(document).on('click', '.added', function(e){
    e.preventDefault();  
  alert("Clicked on .added");
})

JSFiddle: https://jsfiddle.net/n837rw5h/

sam
  • 1,027
  • 3
  • 11
  • 21
  • Please use **on-site** Stack Snippets rather than off-site resources for live examples. Stack Snippets are the `[<>]` toolbar button; [here's how to do one](https://meta.stackoverflow.com/questions/358992/). – T.J. Crowder Oct 21 '19 at 09:59

2 Answers2

3

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.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
2

Add a check to see if the element has the class.

// handle click and add class
    $('button').on('click', function(e){
        e.preventDefault();
      if($(this).hasClass("added")) {
        alert("Clicked on .added");
      } else {
        $(this).addClass("added");
      }
    })
Fob
  • 180
  • 10