Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery figuring out if parent has lost 'focus'

I'm stuck on figuring out the logic to make a drop down menu keyboard accessible.

The HTML is structured as such (extra class names used for clarity):

<ul>
    <li class="primaryMenuItem">
        <a href="">Link 1</a>
        <ul class="popUpMenu">
            <li><a href="">Sub Link 1</a></li>
            <li><a href="">Sub Link 2</a></li>
        </ul>
    </li>
    <li class="primaryMenuItem">
        <a href="">Link 2</a>
        <ul class="popUpMenu">
            <li><a href="">Sub Link 1</a></li>
            <li><a href="">Sub Link 2</a></li>
        </ul>
    </li>    
</ul>

Link 1 and Link 2, when hovered, will show the sub-menu lists (pull down menu). I have this working just fine with some jQuery and the jQuery hoverIntent plugin.

The catch is that this only works with the mouse at the moment.

Next challenge is to get this to work via the keyboard.

I can easily add a focus event to the top level links that then trigger the secondary menus:

$('ul.primaryMenuItem a:first').focus([call showMenu function]) 

That works fine.

To close the menu, one option is to, when opening another menu, check to see if there is another open already and, if so, close it.

That also works fine.

Where that fails, however, is if you have the last menu open, and tab out of it. Since you haven't tabbed into another menu, this one stays open.

The challenge is to figure out how/when to close the menu and the logic needed (jQuery) to figure it out. Ideally, I'd close the menu when the focus is on an element on the page OTHER than any of the menu's child elements.

Logically, I'm looking for this:

$('li.primaryMenuItem').blur([close $(this).find('ul.popUpMenu'))

However, you can't do that, since the LI doesn't actually have focus, but rather the anchor tag within it.

Any suggestions?

UPDATE:

perhaps a better/simpler way to ask the question:

Via jQuery, is there a way to 'watch' to see if focus has moved outside of all children of a particular object?

like image 956
DA. Avatar asked Feb 03 '10 22:02

DA.


People also ask

How do you know if an element loses focus?

The onfocusout event occurs when an element is about to lose focus. Tip: The onfocusout event is similar to the onblur event. The main difference is that the onblur event does not bubble. Therefore, if you want to find out whether an element or its child loses focus, you should use the onfocusout event.

How do I know if my child's element is clicked?

You can use the event. target to determine what was clicked: $('#daddy'). click(function (e) { alert(e.target.id); // The id of the clicked element });

Which method is triggered when an element loses focus in jQuery?

jQuery focusout() Method The focusout event occurs when an element (or any elements inside it) loses focus. The focusout() method attaches a function to run when a focusout event occurs on the element, or any elements inside it.

How to lose focus jQuery?

Lose focus event can occur mainly through focusout() and blur() method. Both of them lose focus when the method gets triggered. These events differ slightly from each other but all of them serve the main purpose of losing focus.


1 Answers

You can use event bubbling to check what has focus on the focusin event. I had success with the following code:


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

You could(should) probably make it more optimized, but it works.

like image 67
emmychan Avatar answered Nov 23 '22 22:11

emmychan