0

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 );
nmsdvid
  • 2,832
  • 2
  • 21
  • 21
  • What do you mean by "stop the function"? Also, we're not here to write improvements to your code; you should be doing that. – Bojangles Nov 28 '11 at 21:08
  • What is your plugin meant to do exactly? – Brian Driscoll Nov 28 '11 at 21:09
  • Also, your fiddle only contains your plugin's code and no sample use case, which would help a lot in understanding your question, as vague as it is. – Frédéric Hamidi Nov 28 '11 at 21:09
  • Voted to close as it seems as though this should really be on codereview.stackexchange.com – Brian Driscoll Nov 28 '11 at 21:10
  • @Brian, maybe, if nmsdvid improves his question. Otherwise, I don't think codereview would want it anyway. – Frédéric Hamidi Nov 28 '11 at 21:12
  • 3
    You guys are way too quick to close a question. His method started an interval timer and the OP needed to know how to store that timer handle and stop it later. I was about to provide an answer to the question, but you all closed it so quick (in less than 7 mins) that now it won't take my answer. Yes, the question was not very clearly written, but if you just look at the referenced code, you would understand what `stop` meant in the context of the question/code. – jfriend00 Nov 28 '11 at 21:17
  • I've edited the question to add some clarity for the OP and am ready to post an answer if enough other people vote to reopen it. – jfriend00 Nov 28 '11 at 21:22
  • @jfriend00 I agree with what you said, please provide an answer – Francisco Nov 28 '11 at 21:25
  • @Brian Driscoll: This isn't a "refactor my code" question as much as it is a "how do I do X?" question, not a good candidate for Code Review IMO. – BoltClock Nov 28 '11 at 21:25
  • @jfriend00, regarding `way to quick to close a question`, that's not under our individual control, each vote is non-binding but sometimes a consensus forms very quickly. Note that so far the questioner has asked and run away: he neither commented nor improved his question, and BoltClock (congrats :) pasted the fiddle into the question before reopening it himself. So, would we have waited some more time before voting to close, the result would have been the same IMHO. `` – Frédéric Hamidi Nov 28 '11 at 21:34
  • 2
    @FrédéricHamidi - When I say "way too quick to close a question", I was voicing that to everyone who voted to close in the first few minutes of the question without even bothering to look at the referenced code to understand what was being asked. When clarifying questions have been asked, it seems reasonable to allow some amount of time for the OP to respond before immediately voting to close. The newer the OP, the more time might be appropriate since they might not know to be watching for the immediate comments. It was a poorly worded question, but it was understandable with a little work. – jfriend00 Nov 28 '11 at 21:38
  • A little more context: http://stackoverflow.com/questions/8270207/how-to-stop-a-jquery-script – Francisco Nov 28 '11 at 21:44

2 Answers2

3

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 );
jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • Thank you for your help but by 'stop the function' I mean when I click on a #div the plugin stops and by clicking on it again it will run again. sorry for the misunderstanding but iam a jQuery noob. – nmsdvid Nov 28 '11 at 22:43
  • 1
    @nmsdvid - the confusion has nothing to do with your jQuery knowledge. You have not yet described the problem in a clear fashion. You need to go back to your question, use the edit button and tell us how it is supposed to work. What is supposed to happen on the first click? What is supposed to happen on the interval timer? How long is the interval timer supposed to run? What is supposed to happen if it is clicked again? – jfriend00 Nov 28 '11 at 23:32
  • @nmsdvid - I added one more option where the call the plugin() will alterate between starting and stopping so the first click will start and the second click will stop. If you want something different than that, then you have to describe a lot more clearly what you want. I'm just about done trying to guess how you want it to work. – jfriend00 Nov 28 '11 at 23:43
1

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.

Brian Driscoll
  • 19,373
  • 3
  • 46
  • 65