JQuery нужна альтернатива фокусу()
Учитывая разметку образца:
<div>
<input />
<input />
<input />
</div>
Как можно через jQuery определить, что div
потерял фокус?
Я могу использовать focusout()
, но это не совсем то, что мне нужно. С фокусом он будет запускаться как одна вкладка от входа к входу, так как она фактически обнаруживает (через пузырьковое событие), что вход теряет фокус.
Еще один способ сформулировать требование: мне нужно знать, когда фокус переместился OUTSIDE из div.
Я задал аналогичный вопрос раньше:
jquery focusin() и предотвращение барботажа
Но это было связано с всплывающим пользовательским интерфейсом, и можно обойти это, вставив в него пустой DIV и помещая событие click/focus на него как триггер, но это не будет работать для этой ситуации.
Следующей мыслью, которую я имел, было проверить для focusin при вызове фокуса:
$(".myobject").focusout(function(element) {
if(!($(this).focusin())){
console.log('doYourThing ' + $(this));
}
});
Увы, это не работает (я предполагаю, что он оценивает focusin во время события focusout и, как таковой, пока не обнаружил фокуса.
Какие-нибудь умные решения этой проблемы? Возможно, мне не хватает собственного события jQuery, которое делает именно то, что я ищу?
UPDATE:
Собственно, упрощенный вопрос:
Мне нужен эквивалент $('div').blur()
, но это действительно работает на div (поскольку размытие не может быть вызвано из div)
Ответы
Ответ 1
Хорошо, что может быть связано с привязкой обработчика "focus" ко всему, и вы знаете, когда вы не находитесь в <div>
, когда вы получаете событие "focus" в другом месте.
$('body').live('focus', (function() {
var inDiv = false;
return function(e) {
if ($(this).closest('#theDiv').length)
inDiv = true;
else {
if (inDiv)
alert("just lost focus!");
inDiv = false;
}
};
});
Ответ 2
Принимая заостренный ответ и идя немного дальше с ним.
создание плагина с плавающей точкой (простой) focuslost
(function($) {
// will store the last focus chain
var currentFocusChain = $();
// stores a reference to any DOM objects we want to watch focus for
var focusWatch = [];
function checkFocus() {
var newFocusChain = $(":focus").parents().andSelf();
// elements in the old focus chain that aren't in the new focus chain...
var lostFocus = currentFocusChain.not(newFocusChain.get());
lostFocus.each(function() {
if ($.inArray(this, focusWatch) != -1) {
$(this).trigger('focuslost');
}
});
currentFocusChain = newFocusChain;
}
// bind to the focus/blur event on all elements:
$("*").live('focus blur', function(e) {
// wait until the next free loop to process focus change
// when 'blur' is fired, focus will be unset
setTimeout(checkFocus, 0);
});
$.fn.focuslost = function(fn) {
return this.each(function() {
// tell the live handler we are watching this event
if ($.inArray(this, focusWatch) == -1) focusWatch.push(this);
$(this).bind('focuslost', fn);
});
};
})(jQuery);
Пример использования
$("div").focuslost(function() {
$(this).append("<div>Lost Focus!</div>");
});
jsfiddle demo
Ответ 3
Еще один плагин для просмотра - это Бен Альман Плагин внешних событий. Это позволяет вам обнаруживать, когда на что-либо вне определенного элемента и его дочерних элементов срабатывает любое из следующих событий: clickoutside, dblclickoutside, focusoutside, bluroutside, mousemoveoutside, mousedownoutside, mouseupoutside, mouseoveroutside, mouseoutoutside, keydownoutside, keypressoutside, keyupoutside, changeoutside, selectoutside, submitoutside
.