Search code examples
jquerycountdown

After jquery removeClass countdown anyway start again


With a click on a div something happens and also I remove the class from the div, so that nothing happens if I click again on the div. But although the class is away, the next click starts also a jQuery function.

I want a button to click on and then happens:

  • a. a div will hide after x seconds
  • b. another div will show after x seconds
  • c. a countdown runs to show, when the change will happen

That will work great.

If i click first on the button1, the countdown should start (it does).
If i click again on the button1 the countdown should not start again.
(But it does - although I remove the selector class with the first click)

How can I avoid, that the countdown starts again?

$('.button1').click(function() {

  $('.output0').delay(10000).fadeOut(500);
  $('.output1').delay(10500).show(0);

});


$('.button1').click(function() {
  $('.button1').removeClass('button1');
});



(function($) {
  $.fn.countTo = function(options) {
    // merge the default plugin settings with the custom options
    options = $.extend({}, $.fn.countTo.defaults, options || {});

    // how many times to update the value, and how much to increment the value on each update
    var loops = Math.ceil(options.speed / options.refreshInterval),
      increment = (options.to - options.from) / loops;

    return $(this).each(function() {
      var _this = this,
        loopCount = 0,
        value = options.from,
        interval = setInterval(updateTimer, options.refreshInterval);

      function updateTimer() {
        value += increment;
        loopCount++;
        $(_this).html(value.toFixed(options.decimals));

        if (typeof(options.onUpdate) == 'function') {
          options.onUpdate.call(_this, value);
        }

        if (loopCount >= loops) {
          clearInterval(interval);
          value = options.to;

          if (typeof(options.onComplete) == 'function') {
            options.onComplete.call(_this, value);
          }
        }
      }
    });
  };

  $.fn.countTo.defaults = {
    from: 0, // the number the element should start at
    to: 100, // the number the element should end at
    speed: 1000, // how long it should take to count between the target numbers
    refreshInterval: 100, // how often the element should be updated
    decimals: 0, // the number of decimal places to show
    onUpdate: null, // callback method for every time the element is updated,
    onComplete: null, // callback method for when the element finishes updating
  };
})(jQuery);


$('.button1').click(function() {

  jQuery(function($) {
    $('.timer').countTo({
      from: 10,
      to: 0,
      speed: 10000,
      refreshInterval: 50,
      onComplete: function(value) {
        console.debug(this);
      }
    });
  });

});
.button {
  padding: 30px;
  background-color: red;
  width: 200px;
}

.output0 {
  padding: 30px;
  background-color: yellow;
  width: 200px;
}

.output1 {
  padding: 30px;
  background-color: green;
  width: 200px;
  display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="button1 button" style="">
  Button1 to show something after 10 seconds
</div>

<div class="output0" style="">
  I will hide after 10 seconds
</div>

<div class="output1" style="">
  I will show after 10 seconds
</div>

<div class="timer"></div>

View on jsFiddle
Or here on live site


Solution

  • The problem is that your .button1 element still has a click event listener on it, even if you remove the class from it.

    A potential solution would be to use the .one function of jQuery. This will only allow the event to be run once per element per event type. It will require your .click events to be merged into one function like so:

    $('.button1').one('click', function(){
    
      $('.output0').delay(10000).fadeOut(500);
      $('.output1').delay(10500).show(0);
    
      jQuery(function($) {
            $('.timer').countTo({
                from: 10,
                to: 0,
                speed: 10000,
                refreshInterval: 50,
                onComplete: function(value) {
                    console.debug(this);
                }
            });
        });
    });
    

    http://api.jquery.com/one/