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 并使用 $('#dummyDiv') 初始化 previousFilterResult 它工作正常。

有什么方法可以初始化 previousFilterResult 而不在页面上放置一个虚拟 div 以便上面的代码仍然有效?

谢谢。

4

2 回答 2

3

不,你不能。

文档中

重要的是要注意,每个匹配元素都会执行一次回调,而不是整个动画执行一次。

但是您可以轻松地将代码更改为

$('#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;
});

在我看来,这比使用$()感觉像 hack 更干净。

于 2012-12-06T10:13:47.313 回答
0

请从文档中注意这一点:

如果提供,则在动画完成后触发回调。...如果为多个元素设置了动画,请务必注意,每个匹配的元素都会执行一次回调,而不是对整个动画执行一次。

(我的重点)

因此,如果您想调用该函数一次,则需要以另一种方式处理。例如:

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 回答