0

I have a div object that should be clickable when it contains the class "clickable". In the Click function I remove the "clickable" class, but it still fires when clicking the object. Will it continue to fire even when I remove the class?

HTML:

<div class="item-wrap" data-id="218" data-index="4" data-filename="gthspill.jpg">
    <div class="info-wrap">
        <div class="vote-wrap">
            <div class="circle clickable" title="Like" data-toggle="tooltip" data-placement="bottom">
                <i aria-hidden="true" class="icon exist d-none fas fa-thumbs-up"></i>
                <i aria-hidden="true" class="icon no-vote  far fa-thumbs-up"></i>
            </div>
            <div class="existing-wrap d-none">
                <div class="inner">
                    <span class="separator">/</span>
                    <span class="count">0</span>
                </div>
            </div>
        </div>
        <div class="caption-wrap">
            <h2 class="caption">Close Up</h2>
        </div>
    </div>
</div>

jQuery:

$("div.vote-wrap > div.circle.clickable").click(function () {
    let $circle = $(this);

    $circle.removeClass("clickable");
}
SteinTheRuler
  • 3,549
  • 4
  • 35
  • 71
  • 2
    Possible duplicate of [Event binding on dynamically created elements?](https://stackoverflow.com/questions/203198/event-binding-on-dynamically-created-elements) – Zenoo Apr 09 '18 at 08:05
  • _“Will it continue to fire even when I remove the class?”_ - of course it will ... The class was only used in the initial selection of elements, and all elements that had the class at that time, have gotten this event handler assigned. Removing the class doesn’t “turn back time” in that regard. – CBroe Apr 09 '18 at 08:17

3 Answers3

1

Use delegate event on() and unbind the click event with unbind('click') for dynamically created element.

$("div.vote-wrap > div.circle.clickable").on('click',function () {
    let $circle = $(this);

    $circle.removeClass("clickable");
    $circle.unbind('click');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="item-wrap" data-id="218" data-index="4" data-filename="gthspill.jpg">
    <div class="info-wrap">
        <div class="vote-wrap">
            <div class="circle clickable" title="Like" data-toggle="tooltip" data-placement="bottom">
                <i aria-hidden="true" class="icon exist d-none fas fa-thumbs-up"></i>
                <i aria-hidden="true" class="icon no-vote  far fa-thumbs-up"></i>
            </div>
            <div class="existing-wrap d-none">
                <div class="inner">
                    <span class="separator">/</span>
                    <span class="count">0</span>
                </div>
            </div>
        </div>
        <div class="caption-wrap">
            <h2 class="caption">Close Up</h2>
        </div>
    </div>
</div>
Albert Einstein
  • 7,472
  • 8
  • 36
  • 71
1

because you didn't unbind the event in the click callback.

You just remove the class.

$("div.vote-wrap > div.circle.clickable").click(function() {
  let $circle = $(this);

  $circle.removeClass("clickable");
  $(this).unbind('click');//unbind the click event
  alert('clicked , and unbind now!');
})
div.vote-wrap > div.circle.clickable {
  background:pink;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="item-wrap" data-id="218" data-index="4" data-filename="gthspill.jpg">
  <div class="info-wrap">
    <div class="vote-wrap">
      <div class="circle clickable" title="Like" data-toggle="tooltip" data-placement="bottom">click me
        <i aria-hidden="true" class="icon exist d-none fas fa-thumbs-up"></i>
        <i aria-hidden="true" class="icon no-vote  far fa-thumbs-up"></i>
      </div>
      <div class="existing-wrap d-none">
        <div class="inner">
          <span class="separator">/</span>
          <span class="count">0</span>
        </div>
      </div>
    </div>
    <div class="caption-wrap">
      <h2 class="caption">Close Up</h2>
    </div>
  </div>
</div>

and another way:

$("div.vote-wrap").on('click','div.circle.clickable',(function() {
  let $circle = $(this);
  $circle.removeClass("clickable");  
  alert('clicked');
}))
div.vote-wrap > div.circle.clickable {
  background:pink;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="item-wrap" data-id="218" data-index="4" data-filename="gthspill.jpg">
  <div class="info-wrap">
    <div class="vote-wrap">
      <div class="circle clickable" title="Like" data-toggle="tooltip" data-placement="bottom">click me
        <i aria-hidden="true" class="icon exist d-none fas fa-thumbs-up"></i>
        <i aria-hidden="true" class="icon no-vote  far fa-thumbs-up"></i>
      </div>
      <div class="existing-wrap d-none">
        <div class="inner">
          <span class="separator">/</span>
          <span class="count">0</span>
        </div>
      </div>
    </div>
    <div class="caption-wrap">
      <h2 class="caption">Close Up</h2>
    </div>
  </div>
</div>
xianshenglu
  • 4,943
  • 3
  • 17
  • 34
0

The element event handler is attached to is determined when listener is attached, not when the event is emitted.

you could rewrite that code like this:

// element instance is captured once
var $elem = $("div.vote-wrap > div.circle.clickable")
$elem.click(function () {
    let $circle = $(this)

    $circle.removeClass("clickable")
})

For solution to your problem check the answers of this question: Event binding on dynamically created elements?

notgiorgi
  • 1,691
  • 12
  • 27