Фокусировка срабатывает дважды
У меня есть текстовое поле и диалоговое окно Jquery UI. Когда пользователь закончит вводить текстовое поле и нажмет Enter, я хочу отобразить диалоговое окно. Для этого я использую следующий код:
$(document).ready(function () {
var helpDial = $('#helpDialog');
var input = $('#helpSearch');
helpDial.dialog({
width: 800,
autoOpen: false,
modal: true,
title: "Templates",
position: [165, 158]
});
input.focusin(function () {
helpDial.dialog('close');
}).focusout(function () {
helpDial.dialog('open');
}).on('keypress', function (e) {
var code = (e.keyCode ? e.keyCode : e.which);
if (code == 13) {
input.focusout();
return false;
}
});
});
<input id="helpSearch" />
<div id="helpDialog"></div>
Проблема в том, что когда я нажимаю Enter, focusout
вызывается дважды, один из input.focusout()
и второй раз сразу после helpDial.dialog('open')
в focusout
обработчик события. Это приводит к созданию двух фоновых наложений, и когда я закрываю диалоговое окно, одно наложение остается видимым.
Что я делаю неправильно? Есть ли лучший способ справиться с этим сценарием - "нажатие клавиши ввода в текстовом поле открывает диалог jQuery". Благодарю.
3 ответа
Единственный способ предотвратить запуск события - это отсоединить обработчик события. Или, в зависимости от ситуации, примите дифференциальные меры на основе информации, доступной на момент возникновения события.
focusout
событие срабатывает каждый раз, когда элемент теряет фокус. В этом случае каждый раз, когда пользователь нажимает на текстовое поле, focusin
событие сработало. Как только курсор покидает текстовое поле (что происходит при открытии диалогового окна), focusout
событие сработало.
Проблема с вашим кодом в том, что вы принудительно вызываете focusout
событие, а затем focusout
Событие вызывается естественно, когда вы открываете диалог. Итак, измените ваш код следующим образом:
$(document).ready(function () {
var helpDial = $('#helpDialog');
var input = $('#helpSearch');
helpDial.dialog({
width: 800,
autoOpen: false,
modal: true,
title: "Templates",
position: [165, 158]
});
input.on('focusin', function () {
input.on("focusout", textboxFocusOut);
}).on('keypress', function (e) {
var code = (e.keyCode ? e.keyCode : e.which);
if (code == 13) {
textboxFocusOut();
}
});
function textboxFocusOut() {
input.off("focusout", textboxFocusOut);
helpDial.dialog('open');
}
});
Этот код делает привязку функции к focusout
в пределах focusin
обработчик Если пользователь отходит от текстового поля, focusout
будет вызван обработчик события, который немедленно отменяет привязку focusout
событие (для предотвращения связывания функции несколько раз). Если пользователь нажимает клавишу ввода, то функция вызывается вручную, что удаляет focusout
обработчик событий перед открытием диалога, чтобы предотвратить запуск focusout
событие от автоматического запуска при открытии диалога.
Наиболее очевидным решением может быть использование такой переменной, как enter_pressed
информировать focusout
функция:
$(function () {
var helpDial = $('#helpDialog'),
input = $('#helpSearch'),
enter_pressed = false;
helpDial.dialog({
width: 800,
autoOpen: false,
modal: true,
title: "Templates",
position: [165, 158]
});
input.on('focusout', function () {
if( !enter_pressed ) {
helpDial.dialog('open');
} else {
enter_pressed = false;
}
}).on('keypress', function (e) {
var code = (e.keyCode ? e.keyCode : e.which);
if (code == 13) {
enter_pressed = true;
helpDial.dialog('open');
}
});
});
http://jsfiddle.net/joplomacedo/7Fpm4/7/
Тем не менее, я считаю, что есть более чистое решение. Я постараюсь придумать это.
В сторону
Действительно ли нужен обработчик событий.focusin?
http://jsfiddle.net/7Fpm4/2/ я обновил ваш пример, просто изменил input.focusin(function () на input.change(function ())