确定焦点何时出现在元素之外

时间:2016-01-07 00:57:03

标签: javascript jquery html css

我试图看看以下是否可行:

  • 由于性能原因,确定焦点是否发生在元素之外,而不使用文档级全局选择器,例如$(document)$(body)$(window)等。
  • 如果没有全球选择者就无法实现,请以可证明的理由解释自己。重要的是,我理解为什么这对于今天的最新技术是不可行的。
  • Bonus Round :确定任务的最有效(计算时间)选择器/事件处理程序/插件。

My implementation 包含一个非常简单的HTML导航栏,如下面的代码段所示。我在每个<a>标记之间进行原生键盘导航。第一个列表元素是标题,包含可见的锚点,第二个元素

<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>

此导航栏的目标很简单:

  1. 原生键盘标签或shift + tab从锚点到锚点。
  2. 关注内部锚元素时显示下拉菜单。
  3. 在不关注任何内部锚元素时隐藏下拉菜单。
  4. 我有1和2,但由于上面列出的要求,3是棘手的。我知道这可以很容易地使用全局选择器来完成,但是这个挑战是要弄清楚并理解是否可以这样做。

    $(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 - The Dangers of Stopping Event Propagation中所解释的那样,对于这个问题的范围是一种危险的技术,但是如果使用所述技术导致最有效的方法然后我会欢迎它。

2 个答案:

答案 0 :(得分: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/

答案 1 :(得分: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/