首次执行后重新分配事件回调

时间:2013-06-27 00:43:20

标签: jquery callback

问题

如何在首次执行后重新分配jQuery事件处理程序回调?

为什么?

如果你曾经使用DOM和jQuery构建了一个花哨的界面,你知道你在CSS中设置为fadeIn()的项目上使用了那种很酷的display: none方法。因此,自然检查,每次针对设置为不显示的DOM元素运行某些东西时,首先要检查它是否可见。你可能会使用这样的东西:

if (!$('#some-element').is(":visible"))

你把它放在你的事件处理程序回调中,然后整个事情最终会看起来像这样:

$('.clickers').on('click', function() {
    if (!$('#some-element').is(":visible")) {
        $('#some-element').fadeIn('slow'); //Slow because we're cool
    }

    //do everything else
})

如果#some-element之后不应该消失,你仍然会有这个不必要的if语句检查它是否可见,即使我们已经知道它。

解决方案?也许

到目前为止我想到的两个最佳解决方案:

第一

第一个涉及在事件处理程序上使用off()重新分配函数,然后在第一次单击项目后执行另一个on()(或者事件发生,无论可能是什么) :

$('.clicker').on('click',function() {
    if (!$('#some-element').is(':visible')) {
        $('#some-element').fadeIn('slow');
    }
    $('#some-element').html("I was clicked: " + $(this).text());
    $('.clicker').off('click').on('click', function() {
        $('#some-element').html("I was clicked: " + $(this).text());
    });
});

jsFiddle

由于off() on()链,我不喜欢这个。这是很多工作,特别是如果有很多相同的类项来处理事件(所有这些都是为了避免使用简单的if语句)。我也不喜欢它,因为函数可能变得复杂,在第二个回调赋值中必须重复。

第二

第二个解决方案是将回调放回一个单独的函数,然后重新分配函数:

$('.clicker').on('click', function () {
    callback.call(this, $('#some-element'));
    callback = function (display) {
        display.html("I was clicked: " + $(this).text());
    }
    callback.call(this, $('#some-element'));
});

var callback = function (display) {
    if (!display.is(':visible')) {
        display.fadeIn('slow');
    }
    display.html("I was clicked: " + $(this).text());
};

jsFiddle

我不喜欢这个与第一个相同的原因,如果函数更长的话会怎样。这是不是很好?有没有更好的方法来摆脱我对我的实现的两个问题?

1 个答案:

答案 0 :(得分:2)

如果元素已经可见,那么.fadeIn不会做任何我认为的事情,所以检查是不必要的(当然.fadeIn会在内部进行检查。)

我认为没有通用的解决方案。使用方法取决于具体情况。

在您的示例中,您可以事件处理程序拆分为两个,并将应该只执行一次的所有代码移动到其自己的处理程序中。该处理程序将在第一次执行后被删除。

// .one binds an event handler and removes it after the first execution
$('.clickers').one('click', function() {
    $('#some-element').fadeIn('slow'); //Slow because we're cool
}).on('click', function() {
    //do everything else
});

事件处理程序按它们绑定的顺序执行,因此首先会触发淡入。

相关问题