0

I want to have multiple numbers on my web page "spin up" as the page loads, giving an impression like a fruit machine.

This involves a simple function with a delayed loop. The way to do this seems to be to use setTimeout recursively. This works fine for just one number on the page.

However for multiple numbers spinning at the same time, each needs its own spinner object. I used prototypes like this:

var Spinner = function(id){
    this.element = $('#' + id);
    this.target_value = this.element.text()
    this.initial_value = this.target_value - 30;
};

Spinner.prototype.spinUp = function() {

    loop(this.element); 

    function loop(element) {
        element.html(this.initial_value += 1);
        if (this.initial_value == this.target_value) {
                return;
            };
        clr = setTimeout(loop(element), 30);  // 30 millisecond delay
    };
};

var Spinner1 = new Spinner('number')

Spinner1.spinUp();

However putting a recursive function inside the prototype method causes a big crash. Can you see a way around this?

Many thanks!

Derek.

Community
  • 1
  • 1
Derek Hill
  • 5,965
  • 5
  • 55
  • 74

2 Answers2

2

When you say:

clr = setTimeout(loop(element), 30);

you are "calling" the function (then and there), and passing the value it returns as the first parameter to setTimeout(..).

You would want an anonymous function doing that job:

setTimeout(function(){loop(element);}, 30);
UltraInstinct
  • 43,308
  • 12
  • 81
  • 104
2

A couple of issues:

  • loop() is not how you pass a function, it's how you invoke a function.
  • You are not calling the function as a method of the object

Try this:

Spinner.prototype.spinUp = function() {
    var loop = function() {
            this.element.html(this.initial_value += 1);
            if (this.initial_value == this.target_value) {
                return;
            };
            setTimeout(loop, 30); // 30 millisecond delay   
        }.bind(this); //Just flat out bind the function to this instance so we don't need to worry about it
    loop();
};

Demo http://jsfiddle.net/KAZpJ/

Esailija
  • 138,174
  • 23
  • 272
  • 326