jquery focus to sibling without focusing out from parent

1.2k views Asked by At

I am try to iterate through all li elements in ul on keydown event by firing focus() event for next sibling li. In this process, I dont want to focus out from parent ul. But its not happening. Even changing focus on siblings is causing focusout event on parent. I want that only when someone clicks somewhere else on the screen should focus out of parent be fired.

var KEY_DOWN=40;

$(document).on('keydown', 'li', function(e){
 let keyCode = e.keyCode || e.which;
 if(keyCode == KEY_DOWN)
 {
  if($(this).next().length != 0)
  {
   $(this).next().focus();
  }
  else
  {
   $(this).parent().children().first().focus();
  }
  return false;
 }
});

$(document).on('focusout','ul', function(e)
{
 console.log('focused')
});
li
{
  border: 1px solid black;
}

li:focus
{
  background: #999;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul tabindex="-1">
<li tabindex="-1">First</li>
<li tabindex="-1">Second</li>
<li tabindex="-1">Third</li>
</ul>

In the snippet, focused in getting printed on every down key press. How to solve this situation.

2

There are 2 answers

0
Shashwat Kumar On BEST ANSWER

Only way I found was to disable focusout event on parent ul when I am trying to focus any li

var KEY_DOWN=40;

$(document).on('keydown', 'li', function(e){
 let keyCode = e.keyCode || e.which;
 if(keyCode == KEY_DOWN)
 {
                $(document).off('blur','ul', doWork);
  if($(this).next().length != 0)
  {
   $(this).next().focus();
  }
  else
  {
   $(this).parent().children().first().focus();
  }
                $(document).on('blur','ul', doWork);
  return false;
 }
});

doWork = function(e)
{
 console.log('focused')
};

$(document).on('blur','ul', doWork);
li
{
  border: 1px solid black;
}

li:focus
{
  background: #999;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul tabindex="-1">
<li tabindex="-1">First</li>
<li tabindex="-1">Second</li>
<li tabindex="-1">Third</li>
</ul>

2
Kiran Dash On

Due to event bubbling, the focusout event is logging the message for you when you are focusing out of li too. You can use the event data to check from where you have focused out. (Read more here: jQuery figuring out if parent has lost 'focus')

But I would like to mention how I do it. I would rather like to detect click outside my ul.

var KEY_DOWN=40;

$(document).on('keydown', 'li', function(e){
 let keyCode = e.keyCode || e.which;
 if(keyCode == KEY_DOWN)
 {
  if($(this).next().length != 0)
  {
   $(this).next().focus();
  }
  else
  {
   $(this).parent().children().first().focus();
  }
  return false;
 }
});

$(document).on('focusout','ul', function(e)
{
    console.log('focused out of li');
});

$(document).click(function() {
    console.log('focused out of ul');
});

$('ul').click(function(e) {
    e.stopPropagation();
});
li
{
  border: 1px solid black;
}

li:focus
{
  background: #999;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul tabindex="-1">
<li tabindex="-1">First</li>
<li tabindex="-1">Second</li>
<li tabindex="-1">Third</li>
</ul>