The problem is that you did not isolate the loop variable i inside the closure. However, this can be solved much more widely using objects.
First, I present an object that will encapsulate what you want; it gets initialized using a panel item and a function to call when it is counted to 100. Therefore, I will call it BarCounter :
function BarCounter(element, fn) { this.element = element; this.fn = fn; this.text = element.getElementsByTagName('div')[0]; this.counter = 0; }
This is only a constructor; he does nothing useful; it resolves the text element, which is just the first <div> tag that it can find under this element and saves this link for later use.
Now we need a function that will do the job; call it run() :
BarCounter.prototype.run = function() { var that = this; if (this.counter < 100) { this.text.innerHTML = this.counter++; setTimeout(function() { that.run(); }, 70); } else { this.fn(this.element); } }
The function checks if the counter has reached another 100; until then it will update the text element with the current value, increment the counter, and then call itself again after 70 ms. You can see how the reference to this is stored in advance to preserve the context in which the run() function is called later.
When done, it calls the completion function, passing the element in which the BarCounter object is BarCounter .
The completion function is much simpler if you pass the element to be deleted:
function removeDiv(element) { element.parentNode.removeChild(element); }
The final step is to edit the rest of your code:
var array = [1]; for (var i = 0; i < array.length; ++i) { var bar = new BarCounter( document.getElementById('bar' + array[i]), removeDiv ); bar.run(); }
It is very simple; it creates a new BarCounter object and calls its run() method. Done :)
Btw, you have the option to remove an item from an object; this, of course, depends on your own needs.
Demo