ここでの問題はi
、クロージャー内でループ変数を分離していないことです。ただし、これはオブジェクトを使用することでよりエレガントに解決できます。
まず、必要なものをカプセル化するオブジェクトを紹介します。bar 要素と、100 まで数え終わったときに呼び出す関数で初期化されますBarCounter
。
function BarCounter(element, fn)
{
this.element = element;
this.fn = fn;
this.text = element.getElementsByTagName('div')[0];
this.counter = 0;
}
これは単なるコンストラクターです。何も役に立ちません。テキスト要素を解決します。これは<div>
、指定された要素の下にある最初のタグであり、後で使用するためにその参照を保存します。
次に、作業を行う関数が必要です。それを呼びましょう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);
}
}
この関数は、カウンターがまだ 100 に達しているかどうかをチェックします。それまでは、現在の値でテキスト要素を更新し、カウンターを増やしてから、70 ミリ秒後に再び自分自身を呼び出します。関数が後で呼び出されるthis
コンテキストを保持するために、 への参照が事前に保持されていることがわかります。run()
すべてが完了すると、完了関数が呼び出され、BarCounter
オブジェクトが操作する要素が渡されます。
削除する要素を渡すと、完了関数がはるかに簡単になります。
function removeDiv(element)
{
element.parentNode.removeChild(element);
}
最後のステップは、残りのコードを調整することです。
var array = [1];
for (var i = 0; i < array.length; ++i) {
var bar = new BarCounter(
document.getElementById('bar' + array[i]),
removeDiv
);
bar.run();
}
今はとても簡単です。新しいオブジェクトを作成し、そのメソッドBarCounter
を呼び出します。run()
終わり :)
ところで、オブジェクト内から要素を削除するオプションもあります。もちろん、これはあなた自身のニーズに依存します。
デモ