0

I need to keep focus/tabbing inside of an overlay modal with a list of items when tabbed BOTH forwards and backwards.

I'm working off of this answer: Keep tabbing within modal pane only

Below is my attempt up to this point:

$(function() {
    $("#show-overlay").on("click", function(){
        $("#overlay-navigation").toggle();
        $(this).text(function(i, text){
            return text === "Show Overlay" ? "Hide Overlay" : "Show Overlay";
        })
    });
  
    $('#overlay-navigation ul li:last-child').on('keydown', function (e) { 
       if ($("this") && (e.which == 9)) {
            e.preventDefault();
            $('#overlay-navigation ul li:first-child').focus();
      }
        if ($("#overlay-navigation ul li:first-child:focus") && (e.shiftKey && e.keyCode == 9)) {
            e.preventDefault();
            $('#overlay-navigation ul li:first-child').focus();
   }
    });
});
#navigation li a {
  color: #000;
  text-decoration: none;
}

#overlay-navigation {
  display: none;
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  background-color: #000;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="navigation">
  <ul>
    <li> <a href="">Item</a> </li>
    <li> <a href="">Item</a> </li>
    <li> <a href="">Item</a> </li>
    <li> <a href="">Item</a> </li>
  </ul>
</div>

<button id="show-overlay">Show Overlay</button>

<div id="overlay-navigation">
  <ul>
    <li> <a href="">Item</a> </li>
    <li> <a href="">Item</a> </li>
    <li> <a href="">Item</a> </li>
    <li> <a href="">Item</a> </li>
  </ul>
</div>

Basically my thought process here is that much like the most upvoted answer in the question attached, I can keep my focus inside the modal back to the first item when the last item is focused. However, in that specific example it doesn't work.

I also need to be able to tab backwards (and check how to see if the shift and tab key is being pressed. I learned how to do that in this answer here: Is the shiftkey held down in JavaScript) to stay inside the modal, which is basically the same thing as forwards but backwards so:

if ($("#overlay-navigation ul li:first-child:focus") && (e.shiftKey && e.keyCode == 9)) {
    e.preventDefault();
    $('#overlay-navigation ul li:first-child').focus();
}

However what I'm finding is that it still escapes the modal backwards.

How can I keep forward and backward tabbing inside of an overlay modal?

f-CJ
  • 4,235
  • 2
  • 30
  • 28
kawnah
  • 3,204
  • 8
  • 53
  • 103

1 Answers1

0

if ($("this") will always be true, as this is a jquery object and this used incorrectly (it is not a string).

if ($("#overlay-navigation ul li:first-child:focus") - same here. True, object with 0 length.

li can't get a focus in your example (it can with tabindex though), so proper focusing would be like this: $('#overlay-navigation ul li:first-child a').focus();

Also, it is written incorrectly (You are not handling reverse navigation properly as you listening keydown for the last item only).

I've made a simple sketch independent from list (it may be modified on the fly, so it checks last/first each trigger).

$(function() {
  $("#show-overlay").on("click", function() {
    $("#overlay-navigation").toggle();
    $(this).text(function(i, text) {
      return text === "Show Overlay" ? "Hide Overlay" : "Show Overlay";
    })
  });

  $('#overlay-navigation ul li').on('keydown', function(e) {
    if (e.keyCode !== 9 || !$(this).is(':first-child') && !$(this).is(':last-child')) {
      return
    } // skip

    if ($(this).is(':first-child') && e.shiftKey) {
      e.preventDefault();
      $('#overlay-navigation ul li:last-child a').focus();
      return;
    }

    if ($(this).is(':last-child')) {
      if (e.shiftKey) {
        return
      } // skip
      e.preventDefault();
      $('#overlay-navigation ul li:first-child a').focus();
    }

  });
});
#navigation li a {
  color: #000;
  text-decoration: none;
}

#overlay-navigation {
  display: none;
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  background-color: #000;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="navigation">
  <ul>
    <li> <a href="">Item</a> </li>
    <li> <a href="">Item</a> </li>
    <li> <a href="">Item</a> </li>
    <li> <a href="">Item</a> </li>
  </ul>
</div>

<button id="show-overlay">Show Overlay</button>

<div id="overlay-navigation">
  <ul>
    <li> <a href="">Item</a> </li>
    <li> <a href="">Item</a> </li>
    <li> <a href="">Item</a> </li>
    <li> <a href="">Item</a> </li>
  </ul>
</div>
extempl
  • 2,987
  • 1
  • 26
  • 38