4

100% の進行が完了するまで関数を呼び出すタイムアウトがあります。次に、割り当てた機能を実行します。それに与えられた値だけが未定義であるか、少なくともその一部です。

どの段階でコードが渡された値を失っているundefinedかはわかりませんが、それを返すようにしていますが、あなたがそれを見るために動作中の JS Fiddle を作成しました:

JSフィドル

私の最終結果は、正しい値を受け取り、次のように指定された要素を削除することです:

function rmv_div(div_id) {
   //div_id is not properly defined so cannot find the div.
    document.getElementById('result').innerHTML = div_id;
    var div = document.getElementById(div_id);
    div.parentNode.removeChild(div);
}
4

2 に答える 2

1

i問題は、内部で使用される変数funcがその関数のスコープ外で作成され、反復ごとに増加することです。func次に、最後に呼び出すとiequals array.lengtharray[i]未定義です。

増加しない各反復で別の変数を作成して解決できます。

解決策 1 :

デモ:http://jsfiddle.net/qJ42h/4/ http://jsfiddle.net/qJ42h/11/

for (var i = 0; i < array.length; i++) {
    var bar = document.getElementById('bar' + array[i]),
        text = document.getElementById('text' + array[i]),
        remove = 'wrap' + array[i],
        j = i;
    do_something(bar, text, function () {
        rmv_div('id' + array[j]);
    }, 1);

}

解決策 2

デモ:http://jsfiddle.net/qJ42h/8/ http://jsfiddle.net/qJ42h/12/

for (var i = 0; i < array.length; i++) {
    var bar = document.getElementById('bar' + array[i]),
        text = document.getElementById('text' + array[i]),
        remove = 'wrap' + array[i];
    do_something(bar, text, (function(i) {
        return function(){ rmv_div('id' + array[i]); }
    })(i), 1);
}
于 2013-07-25T01:14:57.630 に答える
1

ここでの問題は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()終わり :)

ところで、オブジェクト内から要素を削除するオプションもあります。もちろん、これはあなた自身のニーズに依存します。

デモ

于 2013-07-25T02:56:57.203 に答える