将焦点移到Next“li”元素,忽略所有嵌套元素

问题描述 投票:0回答:2

我有如下结构的菜单。

$('html').removeClass('no-js');
// Add plus mark to li that have a sub menu
$('li:has("ul") > a').append('<span class="plusMark">+</span>');

Mousetrap.bind('down', function(e) {

  if ($(".manu-t").children("ul").children("li").children(":focus").length != 0) {
    //mentioned below What I have tried till now
  }

});
#nav,
#nav ul,
#nav li {
  margin: 0;
  padding: 0;
  border: 0;
  list-style: none;
  box-sizing: border-box;
}

#nav {
  position: relative;
  min-height: 30px;
  max-width: 100%;
  background-color: #b5b5b5;
  color: #000;
}

#nav li {
  position: relative;
}

#nav a {
  text-decoration: none;
  height: 100%;
  display: block;
  padding: 0 20px;
}

#nav>ul,
.fa {
  height: 30px;
  line-height: 30px;
}

#nav>ul>li {
  position: relative;
  text-align: center;
}

#nav>ul>li>a {
  background-color: #b5b5b5;
}

#nav>ul>li>a:hover,
#nav>ul>li>a:focus,
#nav>ul>li>a.js-openSubMenu {
  background-color: #5f5f5f;
}

#nav>ul>li:hover>a,
#nav>ul>li:focus>a {
  background-color: #5f5f5f;
  color: #fff;
}

#nav>ul>li>ul>li>a {
  background-color: #5f5f5f;
}

#nav>ul>li>ul>li>a:hover,
#nav>ul>li>ul>li>a:focus {
  background-color: #b5b5b5;
}

#nav>ul>li>ul>li:not(:last-child) a {
  border-bottom: 1px solid #b5b5b5;
}

#nav>ul>li>ul>li>ul>li>a {
  background-color: #b5b5b5;
}

#nav>ul>li>ul>li>ul>li>a:hover,
#nav>ul>li>ul>li>ul>li>a:focus {
  background-color: #5f5f5f;
}

#nav>ul>li>ul>li>ul>li:not(:last-child)>a {
  border-bottom: 1px solid #5f5f5f;
}


/* Javascript classes */

#nav .js-hideElement {
  display: none;
}

#nav .js-showElement {
  display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div class="containe-header">
  <nav id="nav">
    <ul>
      <li class="menu-t"><a href="#">Main</a>
        <ul>
          <li><a href="#">Item1</a>
            <ul>
              <li><a href="#">Sub Item 1</a></li>
              <li><a href="#">Sub Item 2</a></li>
              <li><a href="#">Sub Item 3</a></li>
              <li><a href="#">Sub Item 4</a></li>
            </ul>
          </li>
          <li><a href="#">Item2</a>
            <ul>
              <li><a href="#">Sub Item 1</a></li>
              <li><a href="#">Sub Item 2</a></li>
              <li><a href="#">Sub Item 3</a></li>
              <li><a href="#">Sub Item 4</a></li>
              <li><a href="#">Sub Item 5</a></li>
              <li><a href="#">Sub Item 6</a></li>
            </ul>
          </li>
          <li><a href="#">Item3</a></li>
          <li><a href="#">Item4</a></li>
        </ul>
      </li>
      <li class="menu-l"><a href="#">Menu2</a></li>
    </ul>
  </nav>
</div>

问题是通过按下向下箭头键将焦点从Item1移动到Item2并移动到Item3 ......(我使用了Mousetrap库来检测按键)

到目前为止我尝试了什么..

1.

var focused_index = 1;
focused_index=focused_index - 1;
$('a').eq(focused_index).focus();

但是这个方法侧重于嵌套元素意味着从item1到Sub Item 1再到Sub Item 2等等。

2.

// Get the focused element:
var $focused = $(':focus');

// No jQuery:
var focused = document.activeElement;

// Does the element have focus:
var hasFocus = $('foo').is(':focus');

// No jQuery:
elem === elem.ownerDocument.activeElement;

但这会导致其他元素在Body标记内有焦点的问题。

  1. 回答这个问题Send focus to dynamic li with jQuery

那么如何将焦点从Item1移动到Item2。

javascript jquery html css
2个回答
1
投票

我想专注于Item2的元素。然后到Item3的元素。

您可以使用:

$("a:focus").closest("li").next().find("a").first().focus();

工作片段:

// Add plus mark to li that have a sub menu
$('li:has("ul") > a').append('<span class="plusMark">+</span>');

// set initial focus
$("#nav>ul>li.menu-t>ul>li>a:first()").focus();

$(document).on("keydown", function(e) {

  if (e.keyCode == 40) {
     $("a:focus").closest("li").next().find("a").first().focus();
     return false;
  } 
  if (e.keyCode == 38) {
     $("a:focus").closest("li").prev().find("a").first().focus();
     return false;
  }
  
  //if ($(".manu-t").children("ul").children("li").children(":focus").length != 0) {
    //mentioned below What I have tried till now
  //}

});
a { text-decoration: none; }
:focus { background-color: yellow; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div class="containe-header">
  <nav id="nav">
    <ul>
      <li class="menu-t"><a href="#">Main</a>
        <ul>
          <li><a href="#">Item1</a>
            <ul>
              <li><a href="#">Sub Item 1</a></li>
              <li><a href="#">Sub Item 2</a></li>
              <li><a href="#">Sub Item 3</a></li>
              <li><a href="#">Sub Item 4</a></li>
            </ul>
          </li>
          <li><a href="#">Item2</a>
            <ul>
              <li><a href="#">Sub Item 1</a></li>
              <li><a href="#">Sub Item 2</a></li>
              <li><a href="#">Sub Item 3</a></li>
              <li><a href="#">Sub Item 4</a></li>
              <li><a href="#">Sub Item 5</a></li>
              <li><a href="#">Sub Item 6</a></li>
            </ul>
          </li>
          <li><a href="#">Item3</a></li>
          <li><a href="#">Item4</a></li>
        </ul>
      </li>
      <li class="menu-l"><a href="#">Menu2</a></li>
    </ul>
  </nav>
</div>

0
投票

您可以使用CSS选择器将要“聚焦”的元素存储在数组中。为'keydown'事件添加事件处理程序 - 如果e.code显示用户单击向下箭头然后迭代到数组中的下一个元素。我通过使用生成器函数来做到这一点,当我们到达数组的末尾时,它会旋转回0索引:

function* nextElGenerator() {
  var liEls = document.querySelectorAll('.menu-t > ul > li > a:first-child');

  var i = 0;

  while (true) {
    yield liEls[i];
    i += 1;

    if (i === liEls.length) {
      i = 0;
    }
  }
}

const bulletElItr = nextElGenerator();
let curEl;

document.addEventListener('keydown', e => {
  if (e.code === 'ArrowDown') {
    if (curEl) {
      curEl.style.backgroundColor = 'transparent';
    }
    curEl = bulletElItr.next().value;
    curEl.style.backgroundColor = 'yellow';
  }
});
<div class="containe-header">
  <nav id="nav">
    <ul>
      <li class="menu-t"><a href="#">Main</a>
        <ul>
          <li><a href="#">Item1</a>
            <ul>
              <li><a href="#">Sub Item 1</a></li>
              <li><a href="#">Sub Item 2</a></li>
              <li><a href="#">Sub Item 3</a></li>
              <li><a href="#">Sub Item 4</a></li>
            </ul>
          </li>
          <li><a href="#">Item2</a>
            <ul>
              <li><a href="#">Sub Item 1</a></li>
              <li><a href="#">Sub Item 2</a></li>
              <li><a href="#">Sub Item 3</a></li>
              <li><a href="#">Sub Item 4</a></li>
              <li><a href="#">Sub Item 5</a></li>
              <li><a href="#">Sub Item 6</a></li>
            </ul>
          </li>
          <li><a href="#">Item3</a></li>
          <li><a href="#">Item4</a></li>
        </ul>
      </li>
      <li class="menu-l"><a href="#">Menu2</a></li>
    </ul>
  </nav>
</div>
© www.soinside.com 2019 - 2024. All rights reserved.