如何在首次执行后重新分配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());
});
});
由于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());
};
我不喜欢这个与第一个相同的原因,如果函数更长的话会怎样。这是不是很好?有没有更好的方法来摆脱我对我的实现的两个问题?
答案 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
});
事件处理程序按它们绑定的顺序执行,因此首先会触发淡入。