1

问题

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

为什么?

如果您曾经使用 DOM 和 jQuery 构建过精美的界面,那么您就会知道您在 CSSfadeIn()中设置的项目上使用了那个很酷的方法。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

我不喜欢这个,原因与第一个相同,如果函数更长的话怎么办。这是最好的吗?有没有更好的方法来解决我在实现中遇到的两个问题?

4

1 回答 1

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
});

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

于 2013-06-27T00:48:55.693 回答