最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - React: How to shift focus using arrow keys? (TreeView) - Stack Overflow

programmeradmin0浏览0评论

I am looking for solution which allow to focus elements inside treeview using arrow keys.

Currently, I have treeView (ul) and treeNode (li). Each treeNode may have their own treeView and so on. Every treeNode has tabIndex="0" property to add possibility navigate trough the treeView using Tab key. It works fine. But I would like to add keyboard arrow support to do the same thing.

Any idea how to do this? P.S. I don't want to use any 3rd party libs expect pure React, JS.

<section>
  <header>
    { title }
  </header>
  <ul>
    <li>
      <section>
        <header>
          { title }
        </header>
        <ul>
          // etc.
        </ul>
      </section>
    </li>
  </ul>
<section>

I am looking for solution which allow to focus elements inside treeview using arrow keys.

Currently, I have treeView (ul) and treeNode (li). Each treeNode may have their own treeView and so on. Every treeNode has tabIndex="0" property to add possibility navigate trough the treeView using Tab key. It works fine. But I would like to add keyboard arrow support to do the same thing.

Any idea how to do this? P.S. I don't want to use any 3rd party libs expect pure React, JS.

<section>
  <header>
    { title }
  </header>
  <ul>
    <li>
      <section>
        <header>
          { title }
        </header>
        <ul>
          // etc.
        </ul>
      </section>
    </li>
  </ul>
<section>

Share Improve this question asked Jun 28, 2017 at 14:38 Roman MahotskyiRoman Mahotskyi 6,6858 gold badges49 silver badges93 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 5

I have found a solution to move focus within treeView. First of all you should find all your nodes inside your tree. Then you can find focused element using document.activeElement. After that, you be able to find this item within your array nodes. (document.activeElement == nodes[i]) and remember index i. To move focus using arrow keys, just add eventListener to your node and handle it.

For example, to move upward you can do something like this:

if(arrowUp) { elements[i + 1].focus() }

Roman's answer is helpful. I took this a step further by creating functions that handle moving focus up or down.

In the ponent I have my handleKeyDown function called on the onKeyDown event:

<UnorderedList id='unordered-list' onKeyDown={handleKeyDown} />

To call the functions I used an if statement like this below in my onKeyDown handler:

    const handleKeyDown = (e) => {
    if(e.key === 'ArrowDown') {
        moveFocusDown()
    }
    if(e.key === 'ArrowUp') {
        moveFocusUp()
    }
}

Next for the moveFocusDown function, I did the following:

    const moveFocusDown = () => {
    const listItems = document.querySelector('#unordered-list').childNodes
    const activeItem = document.activeElement
    for(let i = 0; i < listItems.length; i++) {

        const listLength = listItems.length
       if(activeItem === listItems[i] && activeItem !== listItems[listLength - 1]) {
        listItems[i + 1].focus()
       }
    }
}

The conditional activeItem === listItems[i] && activeItem !== listItems[listLength - 1] checks that the activeItem and the current index of the Unordered List child nodes are the same, then checks that the last element in the node list isn't the active element. This is needed to prevent moving focus to an element that doesn't exist.

The moveFocus up function is a little simpler:

    const moveFocusUp = () => {
    const listItems = document.querySelector('#menu').childNodes
    const activeItem = document.activeElement
    for(let i = 0; i < listItems.length; i++) {
       if(activeItem === listItems[i] && activeItem !== listItems[0]) {
        listItems[i - 1].focus()
       }
    }
}
发布评论

评论列表(0)

  1. 暂无评论