2009-11-08 2 views
1

Я связывание 3 события:переплет события, останавливая несколько действий

$("#form").bind('keyup change submit',function(event){ 
    //do something 
    alert("test alert"); 
}); 

В форме вы можете иметь текстовые поля, выпадающие, флажки и т.д. ....

Из того, что я заметил, то Событие «change» не запускается с текстовыми полями, пока вы не нажмете «снаружи» текстового поля. Итак, я использую событие «keyup», которое отлично работает для меня.
И событие «Отправить» само собой разумеется. (Я в основном сберегаю себя от выполнения нескольких селекторов, связывая эти события.) И, возможно, я захочу добавить больше событий позже.

Вот моя проблема ....

всплывающее предупреждение сработает 2x, когда я внести изменения в текстовое поле. Не уверен, что это потому, что я нажимаю кнопку во всплывающем окне, которое вызывает ее, или если изменение значения в текстовом поле также может одновременно активировать изменения в событии &.

В любом случае, это сводит меня с ума.

Любые мысли об улучшении этого метода без использования нескольких селекторов?

ответ

0

Почему бы вам не установить булевский флаг где-нибудь за пределами функций обратного вызова (по-прежнему в общем объеме). Первый вызов установит флаг и выполнит, остальные будут видеть флаг и вернуться. Вы можете сбросить флаг, когда пользователь закрывает окно предупреждения.

EDIT: Еще один вариант, если вы все еще хотите, чтобы разные элементы могли выдавать эти предупреждения, обработчик удаляет себя как прослушиватель событий. Затем вы можете зарегистрировать его, когда окно предупреждения закрывается.

0

Второе предупреждение запускается первым. Когда появляется первое предупреждение, текстовое поле теряет фокус, и событие изменения запускается. Если ваш реальный обработчик не приводит к тому, что текстовое поле теряет фокус, который не должен быть проблемой. Однако вы можете указать ignore событие изменения в текстовых полях, потому что вы уже используете keyup для обработки этих полей.
Используя идею флага от Ryan Lynch, вы можете сделать следующее:

var target = null; 
$("#form").bind('keyup change submit',function(event){ 
    if (event.type == 'keyup') { 
     target = event.target; 
    // a change event after one or more keyup events in the same element 
    } else if (event.type == 'change' && target === event.target) { 
     //do nothing 
     return false; 
    } 
    // actual handler code 
    alert(event.type) // test code 
}); 

Испытано на Firefox. Надеюсь, это поможет.

+0

Несомненно, 'target === event.target' всегда false, поскольку' target' не определен? – Eric

+0

'target' -' null 'до тех пор, пока не произойдет событие keyup.Когда пользователь печатает, запускаются несколько событий keyup, таким образом устанавливая «target» для текущего элемента. Когда событие изменения запускается на этом элементе (после потери фокуса), значение target = event.target равно true. –

1

Редактировать: Я только что увидел вашу заметку о том, что «не имеет нескольких селекторов». При желании можно прикрепить цепь, если это так или иначе поместит счет.

Чтобы быть наиболее эффективным с памятью, я бы разбил это на несколько утверждений.

//Your function 
var handler = function(e) { alert('blah'); }; 

$('#form input[type=text], #form textarea').keyup(handler); 
$('#form select, #form checkbox, #form radio').change(handler); 
$('#form').submit(handler); 

Это хорошо, потому что элементы только запускают одно событие, и это то, что может вам помочь.

На стороне примечания, если вы ожидаете поддержки IE 6, событие изменения не запускается до тех пор, пока флажок/радио/выбор не будет размываться, поэтому вы можете обращаться с ними по-другому (щелкните по-прежнему хорошо работает для флажка/радио).

+0

OP должен * действительно * разделить его, а не свертывать один монолитный doitall через if-soup. –