jQuery: отсоедините обработчики событий, чтобы связать их позже
Кто-нибудь знает, как отменить привязку множества обработчиков событий, но запомнить их, чтобы связать их позже? Какие-либо предложения?
7 ответов
В данных элемента есть элемент событий. Это должно помочь вам начать работу, вы можете прочитать ваши элементы и сохранить обработчики в массиве перед отменой привязки. Прокомментируйте, если вам нужна дополнительная помощь. Я понял эту идею, прочитав метод $.fn.clone, так что взгляните и на это.
$(document).ready(function() {
$('#test').click(function(e) {
alert('test');
var events = $('#test').data("events");
$('#test').unbind('click', events.click[0]);
});
});
<a id="test">test</a>
Вот как этого добиться, обеспечивает storeEvents
и restoreEvents
методы на подбор. storeEvents
делает снимок событий в момент его вызова. restoreEvents
восстанавливает до последнего предыдущего снимка. Возможно, потребуется немного повернуть его для параметризации отмены привязки при восстановлении, возможно, вы захотите сохранить связанные события после последнего снимка.
(function($){
function obj_copy(obj){
var out = {};
for (i in obj) {
if (typeof obj[i] == 'object') {
out[i] = this.copy(obj[i]);
}
else
out[i] = obj[i];
}
return out;
}
$.fn.extend({
storeEvents:function(){
this.each(function(){
$.data(this,'storedEvents',obj_copy($(this).data('events')));
});
return this;
},
restoreEvents:function(){
this.each(function(){
var events = $.data(this,'storedEvents');
if (events){
$(this).unbind();
for (var type in events){
for (var handler in events[type]){
$.event.add(
this,
type,
events[type][handler],
events[type][handler].data);
}
}
}
});
return this;
}
});
})(jQuery);
Поскольку jQuery 1.4.2+ меняет способ хранения обработчиков событий, это представляется актуальным:
Лучший способ, который я нашел, это использовать пространство имен событий:
var ary_handlers = [ fn_highlight, fn_onpress, fn_cleanup ];
for ( idx = 0; idx < ary_handlers.length; idx++ ){
$('#test').bind('click.foobar',ary_handlers[idx]);
}
// and then later:
$('#test').unbind('.foobar');
В приведенном выше примере все события foobar не связаны. Обратите внимание, что если вам нужен более точный контроль зерна, вы можете указать пространство имен для каждого обработчика кликов и соотнести его с вашим массивом обработчиков:
var ary_handlers = [ fn_highlight, fn_onpress, fn_cleanup ];
for ( idx = 0; idx < ary_handlers.length; idx++ ){
$('#test').bind('click.ns_' + String(idx), ary_handlers[idx]);
}
// and then later you could pick off a specific one to unbind
$('#test').unbind('.ns_2');
Существует плагин jQuery под названием Copy Events, который копирует события из одного объекта в другой. Это можно очень легко использовать для "сохранения" событий из одного элемента и их последующего возврата. Еще один вариант:)
Редактировать: исправлена неработающая ссылка
Вы могли бы использовать event.handler
параметр:
$(document).ready(function() {
$('#test').click(function(e) {
e.preventDefault();
alert('test');
$('#test').unbind('click', e.handler);
//Do Something...
$('#test').click();
});
});
<a id="test">test</a>
event.handler
возвращает текущий обработчик, который получил событие, поэтому, пропустив его, вы можете оставить другие обработчики.
Чтобы отменить привязку обработчика события, вам нужно передать функцию обработчика в unbind(). Итак, у вас уже есть функция обработчика, все, что вам нужно сделать, это запомнить ее.
Ник Крэйвер, кажется, имеет правильный ответ для jQuery 1.4.2+. Он также включает полезную скрипку. Его решение позволяет вам извлечь все обработчики событий, прикрепленные к элементу jQuery, и выяснить, к какому обработчику они были присоединены.