Как определить, куда направился фокус? - PullRequest
15 голосов
/ 17 августа 2011

Это было задано здесь ранее, но несколько лет назад, и в то время не было кроссплатформенного решения (кроме решения setTimeout, которое на самом деле не очень удобно).

Я хотел бы сделать onblur="foo(parm);" и иметь возможность foo определить, какой элемент теперь имеет фокус.

Я использую обычный JavaScript;нет jQuery для этого, пожалуйста.

Возможно ли это в наши дни?

Ответы [ 3 ]

7 голосов
/ 17 августа 2011

Вы можете попробовать что-то вроде этого:

function whereDidYouGo() {
    var all = document.getElementsByTagName('*');

        for (var i = 0; i < all.length; i++)
            if (all[i] === all[i].ownerDocument.activeElement)
                return all[i];
}

РЕДАКТИРОВАТЬ:

function whereDidYouGo() { return document.activeElement; }
3 голосов
/ 17 августа 2011

В jQuery, по запросу ОП:

$(':input').blur(function() {
    $focusedElement = $(':input:focus');
    //Do stuff with $focusedElement
}
2 голосов
/ 17 августа 2011

Интересный вопрос. Суть дела в том, когда происходит событие «фокус», до или после события размытия? Если он срабатывает до события размытия, проблема проста, потому что вы можете просто сохранить текущий фокус в переменной, к которой имеет доступ ваше событие размытия.

Однако, по крайней мере, в Chrome 13 кажется, что событие размытия происходит за до события фокусировки. Одно из возможных решений.

С учетом следующего HTML:

<input id="foo" value='foo' />
<input id="bar" value='bar' />

Вы можете:

var currentFocus;
var pendingBlur;

var foo = document.getElementById('foo');
foo.addEventListener('focus', function(){ 
    currentFocus = foo;
    if(pendingBlur !== undefined){
        pendingBlur();
        pendingBlur = undefined;
    }
});
foo.addEventListener('blur', function(){
    pendingBlur = function(){
        console.log('new focus:', currentFocus);
    };
});

var bar= document.getElementById('bar');
bar.addEventListener('focus', function(){ 
   currentFocus = bar;
   if(pendingBlur !== undefined){
        pendingBlur();
        pendingBlur = undefined;
   }
});
bar.addEventListener('blur', function(){
    pendingBlur = function(){
        console.log('new focus:', currentFocus);
    };
});

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

Вот рабочий пример в JSFiddle.

РЕДАКТИРОВАТЬ: Это решение страдает от проблемы, заключающейся в том, что если вы размыли форму, щелкнув по чему-то другому , чем другой элемент формы, событие размытия никогда не сработает (так как мы ожидаем события фокуса). Единственный способ обойти это, что я могу себе представить, - это использовать таймер, чтобы проверить, определен ли pendingBlur, и если да, вызвать его. В этот момент вам больше не нужно событие фокуса для вызова обратного вызова размытия ...

...