nmsdvid
nmsdvid

Reputation: 2898

stop a jQuery plugin

I recently started to work on my first plugin but i am stuck a little. My problem is that after my plugin starts I don't know how to stop it. And by stop it I mean: when I click on a #div the plugin stops and when I click on it again it starts:
Something like this:

$("#div").click(function(){
    $(this).plugin(); // starts the plugin

});

Any ideas?

Here's a demo: http://jsfiddle.net/nmsdvid/hmDyR/

And this is my code so far:

(function( $ ) {
  $.fn.plugin = function(params) {
  params = $.extend( {param1: 10, parma2: 5, param3:0, param4:100}, params);

  var timer = setInterval( plugin, params.param1);
  var showTimes = params.param3;
  var counter = 0;

  function plugin() {
    for (var i = 0; i < params.param2; i++) {
     // code
    }

   if (counter == 0) { counter++; return; }

    $('#div')
      .stop()
      .hide()
      .filter( function() { return this.id.match('frame' + counter); })   
      .show();
    if(counter == params.param2){
       counter = 0;
       showTimes --;
       if(showTimes == 0)
           clearInterval(timer);
    }else{
       counter++;
    }
  }
  return this;
  };

})( jQuery );

Upvotes: 0

Views: 1430

Answers (2)

jfriend00
jfriend00

Reputation: 707476

I presume by "stop the function", you mean stop your interval timer.

To do that, you need to store the timer handle in the jQuery object (as a property using this) and then add a new method to stop it.

You can do that my changing this line:

var timer = setInterval( plugin, params.param1);

to this:

this.pluginTimer = setInterval( plugin, params.param1);

and this line:

clearInterval(timer);

to this line:

clearInterval(this.pluginTimer);

And, then adding this method:

$.fn.stopPlugin = function() {
    clearInterval(this.pluginTimer);
    this.pluginTimer = null;
}

The whole block of code would be this after those changes:

(function( $ ) {
    $.fn.plugin = function(params) {
        params = $.extend( {param1: 10, param2: 5, param3:0, param4:100}, params);

        this.stopPlugin();    
        this.pluginTimer = setInterval( plugin, params.param1);
        var showTimes = params.param3;
        var counter = 0;

        function plugin() {
            for (var i = 0; i < params.param2; i++) {
             // code
            }

            if (counter == 0) { counter++; return; }

            $('#div')
                .stop()
                .hide()
                .filter( function() { return this.id.match('frame' + counter); })   
                .show();
            if(counter == params.param2) {
                counter = 0;
                showTimes --;
                if(showTimes == 0) {
                   this.stopPlugin();
                }
            } else {
               counter++;
            }
        }
        return this;
    };

    $.fn.stopPlugin = function() {
        if (this.pluginTimer) {
            clearInterval(this.pluginTimer);
            this.pluginTimer = null;
        }
    }

})( jQuery );

Style-wise, I would recommend that you use meaningful names for your various parameters options instead of param1, param2, param3 and param4. Pick names like count and duration that say what they are.

If you want the first click to start the plugin and the second click to stop it, you could make the call to plugin() alternate between starting and stopping with this code:

(function( $ ) {
    $.fn.plugin = function(params) {
        params = $.extend( {param1: 10, param2: 5, param3:0, param4:100}, params);

        // if the timer was already running, then stop it and return
        if (this.pluginTimer) { 
            this.stopPlugin();
            return this;
        }
        this.pluginTimer = setInterval( plugin, params.param1);
        var showTimes = params.param3;
        var counter = 0;

        function plugin() {
            for (var i = 0; i < params.param2; i++) {
             // code
            }

            if (counter == 0) { counter++; return; }

            $('#div')
                .stop()
                .hide()
                .filter( function() { return this.id.match('frame' + counter); })   
                .show();
            if(counter == params.param2) {
                counter = 0;
                showTimes --;
                if(showTimes == 0) {
                   this.stopPlugin();
                }
            } else {
               counter++;
            }
        }
        return this;
    };

    $.fn.stopPlugin = function() {
        if (this.pluginTimer) {
            clearInterval(this.pluginTimer);
            this.pluginTimer = null;
        }
    }

})( jQuery );

Upvotes: 3

Brian Driscoll
Brian Driscoll

Reputation: 19635

Here is one issue I found right from the start that likely explains your issue:

Your initial value for showTimes is 0 Later in your code you decrement this value based on a condition:

if(counter == params.param2){
   counter = 0;
   showTimes --;
   if(showTimes == 0)
       clearInterval(timer);
}else{
   counter++; 
}

So, assuming no other changes to showTimes between when its value is set and the conditional decrement, its value will be -1.

Thus, this condition: if(showTimes == 0) will always evaluate to false, and clearInterval is never called.

It's probably also worth noting that you have a typo in your parameter declaration:

  params = $.extend( {param1: 10, parma2: 5, param3:0, param4:100}, params);

Specifically: parma2: 5 should be param2: 5 I believe.

Upvotes: 1

Related Questions