Как определить, куда направился фокус?

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

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

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

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

3 ответов


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

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

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

EDIT:

function whereDidYouGo() { return document.activeElement; }

в jQuery, по запросу OP:

$(':input').blur(function() {
    $focusedElement = $(':input:focus');
    //Do stuff with $focusedElement
}

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

однако, по крайней мере, в 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.

EDIT: это решение страдает от проблемы, что если вы размытие на форме, нажав на что-то другое чем другой элемент формы, событие размытия никогда не срабатывает (так как мы ждем события фокуса). Единственный способ обойти это, то, что я могу понять, использует таймер, чтобы проверить, определен ли pendingBlur, и если да, вызовите его. В этот момент вам больше не нужно событие focus для вызова обратного вызова размытия...