使用箭头键选择列表的子li元素

时间:2018-10-04 21:32:54

标签: javascript jquery css html-lists keyboard-events

我正在尝试创建一个带有子菜单的菜单,这些菜单都可以通过键盘进行导航。本质上,我有一个无序列表,每个列表项下面都有另一个无序列表。我可以这样浏览顶层列表:

var li = $('li.tile');
var liSelected;
$(window).keydown(function(e) {
    if(e.which === 40) {
        if(liSelected) { // just a boolean variable at this point?
            liSelected.removeClass('selected');
            next = liSelected.next();
            if(next.length > 0) {
                liSelected = next.addClass('selected');
            } else {
                liSelected = li.first().addClass('selected');
            }
        } else {
            liSelected = li.first().addClass('selected');
        }
    } else if(e.which === 38) {
        if(liSelected) {
            liSelected.removeClass('selected');
            next = liSelected.prev();
            if(next.length > 0) {
                liSelected = next.addClass('selected');
            } else {
                liSelected = li.last().addClass('selected'); // not properly selecting last() because of submenu items ? 
            }
        } else {
            liSelected = li.last().addClass('selected');
        } 
    } /* begin experiment*/ else if (e.which === 13){
      $(".selected").click();
    } 
});

然后,我尝试在“ else if”语句之前切换到向下键(案例38)之前添加此内容-

 if(liSelected && ($(".subTile").is(":visible"))){
        $(".selected:first-child").addClass("selectedSub");
      }

我不知道为什么它不起作用。

我有两个CSS类,菜单的每个级别一个。 “选择”用于顶层,“ selectedSub”用于底层,它们所做的只是更改项目的背景颜色,以便用户知道它们的位置。

我的子菜单隐藏在开头,它们像这样打开/关闭:

var acc = document.getElementsByClassName("tile");
var i;


for (i=0;i<acc.length;i++){
  acc[i].addEventListener("click", function(){
    this.classList.toggle("active");

    var $subItem = $("ul, li", this);
    this.classList.contains("active") ? $subItem.show() : $subItem.hide() ;
  })
}

我对代码很陌生,目前迷路了。 这对我有帮助,请参考我的codepen:https://codepen.io/kbeats/pen/YJWzeP

1 个答案:

答案 0 :(得分:0)

不建议直接操作DOM。

您可能很难放手(我们都去过那里),但是请尝试通过以下方式重新编写代码。我将分享一个伪代码,说明应该如何做。

$('.select').removeClass('select')

arrayOfListElems = [
   '#li-elem1', 
   '#li-elem1-1', // sub-menu of li-elem1
   '#li-elem1-2', // sub-menu of li-elem1
   '#li-elem2', 
   '#li-elem3', 
]
currIndex = 0;
maxIndex = currIndex.length - 1;

if(key is pressed){
  if(key is down-button){
    currIndex--;
    // makes sure currIndex isn't below 0
    currIndex = currIndex < 0 ? 0 : currIndex; 
  } else if(key is up-button){
    currIndex++;
    // makes sure currIndex isn't below 0
    currIndex = currIndex > maxIndex 
      ? maxIndex 
      : currIndex; 
  }
  currElem = arrayOfListElems[currIndex];

  // do stuff with the element:
  $(currElem).addClass('select')
}

通过这种方式,您只需要以某种方式正确地获得arrayOfListElems,无论是手动对其进行硬编码还是以一种动态方式进行获取,代码都可以正常工作。