jQuery find (': focus') не работает должным образом - PullRequest
2 голосов
/ 21 марта 2011

Я создаю виджет, который скользит в hover с функциями showTracker и hideTracker.Я хочу, чтобы оно не выскользнуло из поля зрения, если оно содержит элемент с сфокусированной формой, поэтому у меня все получилось:

function hideTracker(){
  if($('#tracker').find(':focus').length == 0){ 
    $('#tracker').stop().hide();    
  }
}

Круто.Теперь он не скрывается, если мышь выпадает, если в фокусе есть поле.К сожалению, это также означает, что когда поле теряет фокус (и пришло время скрывать виджет), оно просто остается там.Событие unHover было и прошло.

Итак, я добавил это:

$('#tracker *').blur(function(){
  hideTracker();
}); 

И это тоже работает - с одной маленькой ошибкой, с которой мне нужна помощь!

Еслифокус перемещается от одного элемента в трекере к другому, который также находится в пределах #tracker, трекер прячется.Я подумал, что if($('#tracker').find(':focus').length == 0) вернет false, учитывая, что следующий элемент формы имеет фокус, но я думаю, что это не так.

Это тот случай, когда .blur () срабатывает до того, как следующий элемент достигает фокуса?

Как мне обойти это?

Ответы [ 3 ]

1 голос
/ 21 марта 2011

Хлоп.Tricky.Да, происходит следующее:

  1. mousedown: старый элемент формы получает событие blur.$(':focus').length == 0.
  2. mouseup: новый элемент формы получает событие focus.$newFormElement.is(':focus') == true.

Это улучшение:

$('#tracker').focusout(function() //basically like $('#tracker, #tracker *').blur(), but "this" is always '#tracker'
{
    if(!$(this).is('#tracker:hover')) //for some reason plain old :hover doesn't work, at least on the latest OS X Chrome
        hideTracker();
});

Но оно не идеально.Это действительно работает, только если вы используете мышь.Если вы используете вкладку для перемещения между полями (или каким-либо другим возможным механизмом), когда ваша мышь не находится над #tracker, она не будет работать.


Вот еще одна попытка.Это немного ... хакерски.Суть в том, что вместо обработки события blur вы обрабатываете событие focus для второй вещи, которая сфокусирована.Но!Что если вы нажмете на то, что не может быть сфокусировано?Пустое место на вашей странице?Тогда событие focus не запускается.

Хорошо.Итак, хитрость заключается в следующем: поместите tabindex="0" в корневой тег <html>.Это означает, что всегда есть что-то , которое можно сфокусировать.Так что нет возможности сосредоточиться ни на чем (по крайней мере, я так не думаю).

Тогда вы можете сделать это:

$('*').live('focus', function(e)
{
    if(!$.contains($('#tracker')[0], this)) //if the new thing you focused on is not a descendant of #tracker
        hideTracker();
    e.stopPropagation();
});

Э?Так что да, это сертифицированный хак.Но это сложная проблема, и это лучшее, что я могу придумать в этот час.

1 голос
/ 21 марта 2011

Как насчет этого?

$('body *').focus(function(){
    if(!$(this).is('#tracker *') && $('#tracker:visible').length != 0) hideTracker();
});
0 голосов
/ 23 марта 2011

Спасибо всем за ваши ответы.Использование события .focus () вместо .blur () было разумным способом посмотреть на него.К сожалению, это порождает пару проблем с браузером, и я не мог заставить все вышеперечисленное работать очень надежно.

В конце я решил использовать setTimeout(hideTracker, 100);, чтобы событие focus () могло принятьместо до того, как подсчитано количество сфокусированных элементов в трекере.Не идеально, но работает хорошо, и задержка довольно незаметна.

Еще раз спасибо.

...