jQuery搞清楚父母是否已经失去了“焦点”
我一直坚持要弄清楚下拉菜单键盘可以访问的逻辑。
HTML的结构如此(为了清晰起见,使用额外的类名称):
链接1和链接2,当hover时,将显示子菜单列表(下拉菜单)。 我有一些jQuery和jQuery hoverIntent插件可以正常工作。
问题是这只适用于鼠标。
接下来的挑战是通过键盘使其工作。
我可以轻松地将焦点事件添加到顶级链接,然后触发辅助菜单:
$('ul.primaryMenuItem a:first').focus([call showMenu function])
这很好。
要关闭菜单,一个选项是,当打开另一个菜单时,检查是否已经打开另一个菜单,如果是,则关闭它。
这也很好。
但是,如果你打开了最后一个菜单,那么它就会失败。 由于您没有标记到另一个菜单,这个菜单保持打开状态。
挑战在于弄清楚如何/何时关闭菜单以及需要的逻辑(jQuery)来弄清楚它。 理想情况下,当焦点位于页面上的元素上时,我会关闭菜单,而不是任何菜单的子元素。
逻辑上,我正在寻找这个:
$('li.primaryMenuItem').blur([close $(this).find('ul.popUpMenu'))
但是,您不能这样做,因为LI实际上没有焦点,而是其中的锚标记。
有什么建议?
更新:
也许是一个更好/更简单的问题提问方式:
通过jQuery,有没有办法“观察”以查看焦点是否移动到特定对象的所有子节点之外?
您可以使用事件冒泡来检查焦点事件的焦点。 我使用以下代码取得了成功:
$("li:has(ul.popUpMenu)").focusin(function(e) { $(this).children().fadeIn('slow'); }); $('body').focusin(function(e) { if (!$(e.target).parent().is('ul.popUpMenu li')) { $('ul.popUpMenu').fadeOut('slow'); } });
你可以(应该)使它更优化,但它的工作原理。
使用新的jquery 1.4函数: focusin
和focusout
而不是blur
和focus
。 以下是focusout
不同之处:
当焦点事件或其内部的任何元素失去焦点时,会将焦点事件发送到元素。 这与模糊事件的区别在于它支持从父元素检测焦点丢失(换句话说,它支持事件冒泡)。
如果你这样做怎么样:
$('#link_A_id, #link_A_id > *').focusout(function () { if ($(document.activeElement).closest('#link_A_id').length == 0) //focus is out of link A and it's children });
试试这个
$('li.primaryMenuItem:last li a:last').blur([do whatever you need to do])
从逻辑上讲,如果您的用户标记出来,他一定是在关注最后一个锚。
您甚至可以像这样设置自己的事件处理程序:
$('li.primaryMenuItem:last').bind('myblur', function() ...);
并在最后一个锚点模糊事件中调用它:
...blur(function() { $(this).parents('li.primaryMenuItem').trigger('myblur'); ...
这对我有帮助…… http://plugins.jquery.com/project/focus
它会自动检测您是否仍在父级内。 它基本上改变了jQuery焦点以这种方式工作,我觉得它应该如何工作。
$('#parent').focusout(function () { console.log('focusout of parent'); });
我不明白为什么按Tab键在子元素之间移动文本字段应该触发父节点上的焦点,因为你仍然在父节点内。 必须发生一些让你离开它的东西,我怀疑这是一个错误……有人和我在一起吗? 好吧无论如何上面的插件修复它。 只需在代码之前包含它即可“修复”此问题。 如果不是,我会爱一个人解释为什么这不是一个错误。
谢谢,Dom
我有一个类似的问题…我创建了一个jsfiddle来确定父字段集何时失去焦点然后调用一个函数。 它当然可以优化,但它是一个开始。
function saveFields() { $.each($('fieldset.save'),function(index, value) { // WHERE THE POST WOULD GO alert('saving fieldset with id '+ value.id); $(value).removeClass('save'); }); } $('.control-group').focusin(function(){ var thefield = $(this).parent('fieldset'); if (!thefield.hasClass('active')) { if($('fieldset.active').length > 0){ $('fieldset.active').removeClass('active').addClass('save'); saveFields(); } thefield.addClass('active'); } else { console.log('already active'); } });