Подтвердить что ты не робот

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)

4b9b3361

Ответ 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.