JQuery One - один раз один раз с несколькими типами событий
В соответствии с docs для one
:
Если первый аргумент содержит более одного типа событий, разделенных пробелами, обработчик события называется один раз для каждого типа события.
Есть ли способ запускать одну функцию один раз, когда возникает какое-либо событие?
Пример:
$('input').one('mouseup keyup', function(e){
console.log(e.type);
});
Я хотел бы только один раз вызвать функцию, независимо от того, какое событие запустило ее.
В настоящее время функция будет запускаться один раз для каждого типа события.
Примечание. Я не ищу здесь событие focus
. Это просто пример.
Ответы
Ответ 1
Вместо .one
используйте .on
и удалите привязку вручную с помощью .off
.
$('input').on('mouseup keyup', function(e){
console.log(e.type);
$(this).off('mouseup keyup');
});
Fiddle: http://jsfiddle.net/23H7J/3/
Это можно сделать немного более элегантно с пространствами имен:
$('input').on('mouseup.foo keyup.foo', function(e){
console.log(e.type);
$(this).off('.foo');
});
Это позволяет нам использовать один идентификатор (foo) для удаления любого количества привязок, и мы не будем влиять на другие привязки клавиш или клавиш, которые может иметь элемент.
Fiddle: http://jsfiddle.net/23H7J/41/
Ответ 2
Отличные ответы! Чтобы включить их в функцию, здесь расширение jQuery основывается на текущих ответах:
//The handler is executed at most once per element for all event types.
$.fn.once = function (events, callback) {
return this.each(function () {
$(this).on(events, myCallback);
function myCallback(e) {
$(this).off(events, myCallback);
callback.call(this, e);
}
});
};
Затем назовите это:
$('input').once('mouseup keyup', function(e){
console.log(e.type);
});
Бонус. Это имеет дополнительное преимущество только для отсоединения обработчиков для этой конкретной функции, передав исходный обработчик
Ответ 3
Вы можете просто добавить $('input').off();
в конец вашей функции.
Ответ 4
Чтобы выстрелить один раз и продолжить стрельбу, можно использовать следующий фрагмент:
https://jsfiddle.net/wo0r785t/1/
$.fn.onSingle = function(events, callback){
if ("function" == typeof(callback)) {
var t = this;
var internalCallback = function(event){
$(t).off(events, internalCallback);
callback.apply(t, [event]);
setTimeout(function(){
$(t).on(events, internalCallback);
}, 0);
};
$(t).on(events, internalCallback);
}
return $(this);
};
Он работает, временно отключив события, используя функцию internalCallback
, и асинхронно (setTimeout
) снова включив его.
Большинство других предложений в этом потоке отключить все будущие события на целевой. Однако, хотя OP, похоже, удовлетворен предыдущими ответами, в его вопросе не упоминается постоянное отключение событий.