0

jQueryを使用してページ上のテーブルをフィルタリングしようとしています。現在表示されている行をフェードアウトし、新しい選択に一致する行をフェードインしたいと思います。私のjQueryコードは次のようになります。

$('#details-table tr').hide();
var previousFilterResult = $();
var selects = $('#search-panel > select');
selects.change(function () {
    selects.attr('disabled', 'disabled');
    var filterResult = filterTable();

    previousFilterResult.hide('slow', function () {
        filterResult.fadeIn('slow', function () {
            selects.removeAttr('disabled');
        });
    });

    previousFilterResult = filterResult;
});

私の問題は、previousFilterResultを$()で初期化すると、previousFilterResult.hide呼び出しのコールバックにヒットしないように見えるため、コードが機能しないことです。ページにダミーのdivを配置し、previousFilterResultを$('#dummyDiv')で初期化すると、正常に機能します。

上記のコードが引き続き機能するように、ページにダミーのdivを配置せずにpreviousFilterResultを初期化する方法はありますか?

ありがとう。

4

2 に答える 2

3

いいえ、できません。

ドキュメントから:

コールバックは、アニメーション全体に対して 1 回ではなく、一致した要素ごとに 1 回実行されることに注意してください。

ただし、コードを次のように簡単に変更できます。

$('#details-table tr').hide();
var previousFilterResult = null;
var selects = $('#search-panel > select');
selects.change(function () {
    selects.attr('disabled', 'disabled');
    var filterResult = filterTable();
    var callback = function () {
        filterResult.fadeIn('slow', function () {
            selects.removeAttr('disabled');
        });
    };
    if (previousFilterResult) previousFilterResult.hide('slow', callback);
    else callback();
    previousFilterResult = filterResult;
});

$()これは、私の意見ではハックのように感じる使用よりもクリーンです。

于 2012-12-06T10:13:47.313 に答える
0

ドキュメントからこれに注意してください:

指定した場合、アニメーションが完了するとコールバックが発生します。...複数の要素がアニメーション化されている場合、コールバックは、アニメーション全体に対して 1 回ではなく、一致した要素ごとに 1 回実行されることに注意することが重要です。

(私の強調)

したがって、関数を一度呼び出したい場合は、別の方法で処理する必要があります。例えば:

selects.change(function () {
    var fired = false; // Remember whether we've fired the callback

    selects.attr('disabled', 'disabled');
    var filterResult = filterTable();

    // Do we have any previous result?    
    if (previousFilterResult && previousFilterResult[0]) {
        // Yes, and there's at least one element in the set,
        // hide it/them and schedule a callback
        previousFilterResult.hide('slow', done);
    }
    else {
        // No, go ahead and fire our callback directly
        done();
    }

    previousFilterResult = filterResult;

    function done() {
        // If there were multiple results, we might get multiple calls,
        // so keep track of whether we've been called (fired)
        if (!fired) {
            fired = true;
            filterResult.fadeIn('slow', function () {
                selects.removeAttr('disabled');
            });
        }
    }
});
于 2012-12-06T10:15:41.610 に答える