Determining when focus occurs outside an element

I am trying to check if the following is possible:

  • Determining whether the focus is going element without using selectors global document level, such as $(document), $(body), $(window)etc. due to performance reasons.
  • If this cannot be achieved without global selectors, explain yourself as a demonstrable reason. It is important that I understand why this cannot be accomplished with the help of modern technology.
  • Bonus round : determining the most efficient (calculation time) selector (s) / event handler / plugins (s) for the task.

My implementation consists of a very simple HTML navigation bar, as shown in the snippet below. I use the built-in keyboard navigation between each tag<a>. The first element of the list is the header containing the anchor that is visible, the second element

<ul class="test">
  <li>
    <a href="#">Title</a>
  </li>
  <li>
    <ul>
      <li>
        <a href="#">Some link</a>
      </li>
      <li>
        <a href="#">Some link</a>
      </li>
      <li>
        <a href="#">Some link</a>
      </li>
      <li>
        <a href="#">Some link</a>
      </li>
    </ul>
  </li>
</ul>

The purpose of this navigation bar is simple:

  • A tab opens from the active keyboard or shift + to go from snap to snap.
  • Shows a drop-down menu when focusing on internal snap elements.
  • Hide the dropdown menu if you are not focusing on any internal anchor elements.

I have 1 and 2, but 3 is difficult due to the requirements listed above. I know that this can be easily done with a global selector, but this task is to find out and understand if it can be done otherwise.

$(document).ready(function() {
    dropdownMenu = $(".test > ul");
    dropdownMenu.hide();

    $(".test").focusin(function() {
        if (dropdownMenu.is(":hidden")) {
          dropdownMenu.show();
        }
    });
    // Some selector for some event here to handle the focus/clicks outside the $(".test") element
});

. event.stopPropagation();, CSS Tricks - , , , .

+4
2

, , , :

  var isVisible = false;

  $(".test").focusin(function() {
    if (dropdownMenu.is(":hidden")) {
      dropdownMenu.show();
    }
    isFocused = true;
  });

  $(".test").focusout(function() {
    isFocused = false;
    setTimeout(function() {
      if (!isFocused && dropdownMenu.is(":visible")) {
        dropdownMenu.hide();
      }
    }, 100);
  });

, . . https://jsfiddle.net/d5fa5o8q/4/

+2

, 100%, , .

event.target closest focusin.

$(document).on('focusin', function (event) {
  var $target = $(event.target);
  if (!$target.closest('.bar').length) {
    console.log('You focused outside of .bar!');
  }
});

: https://jsfiddle.net/crswll/qk14r7c7/2/

+2

Source: https://habr.com/ru/post/1623175/


All Articles