2

我正在制作一个小部件,它可以hover通过showTrackerhideTracker功能滑入和滑出视图。如果它包含一个集中的表单元素,我想防止它滑出视图,所以我已经这样做了:

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() 是在下一个元素获得焦点之前触发的情况吗?

我怎样才能解决这个问题?

4

3 回答 3

1

这样的事情怎么样?

$('body *').focus(function(){
    if(!$(this).is('#tracker *') && $('#tracker:visible').length != 0) hideTracker();
});
于 2011-03-21T04:46:04.480 回答
1

哎呀。棘手。是的,正在发生的事情是:

  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();
});

诶?所以,是的,这是一个经过认证的黑客攻击。但这是一个棘手的问题,这是我目前能想到的最好的问题。

于 2011-03-21T05:38:39.033 回答
0

谢谢大家的答案。利用 .focus() 事件而不是 .blur() 是一种聪明的看待它的方式。不幸的是,它确实引发了一些浏览器问题,我无法让上述任何一个工作得非常稳健。

最后,我决定使用setTimeout(hideTracker, 100);允许 focus() 事件在跟踪器中的焦点元素计数被评估之前发生。不理想,但它运行良好,延迟相当难以察觉。

再次感谢。

于 2011-03-23T01:06:54.123 回答