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

javascript - Setting focus on table row elements - Stack Overflow

programmeradmin5浏览0评论

I have a table list of items that I want to be able to scroll through using the keyboard up and down buttons. I am currently able to get the similar desired effect of moving down the list with the tabindex attribute. I am also using ng repeat to generate the instances of the elements. Tips or clues on how to achieve being able to focus and scroll up and down the list by using the up and down keys?

Sample code below.

table ng-if="!toolbarCtrl.loadingContacts" class="table dataTable hover" id="table3">
                <tbody role="alert" aria-live="polite" aria-relevant="all">
                    <tr class="pointer" tabindex="0" ng-repeat="contact in toolbarCtrl.contactEntities | filter:toolbarCtrl.toolbarSearchStringAfterDelay | orderBy: toolbarCtrl.tab == toolbarCtrl.tabs.RECENT ? '-dateSeen' : (toolbarCtrl.tab == toolbarCtrl.tabs.ALL ? '+data.fileAs' : '')"
                        ng-class="" ng-if="toolbarCtrl.toolbarSearchStringAfterDelay" ng-click="toolbarCtrl.selectContact(contact)"> 
                        <td rel="popover_dark" ng-class="contact.loading ? 'contactDisabled' : '' " data-container="body" data-toggle="popover" data-placement="right" data-content="" data-original-title="" title="" class="sorting_1 has_popover">
                        </td>
                    </tr>
                </tbody>
            </table>

I mutated your checkKey function to bee this

 controller.checkKey = function (event) {
        $("tr[tabindex=0]").focus();
        var event = window.event;
        if (event.keyCode == 40) { //down
            var idx = $("tr:focus").attr("tabindex");
            idx++;
            if (idx > 6) {
                idx = 0;
            }
            $("tr[tabindex=" + idx + "]").focus();
        }
        if (event.keyCode == 38) { //up
            var idx = $("tr:focus").attr("tabindex");
            idx--;
            if (idx < 0) {
                idx = 6;
            }
            $("tr[tabindex=" + idx + "]").focus();
        }
    }

I'm close but its skipping straight to the last element. Does this look right?

I have a table list of items that I want to be able to scroll through using the keyboard up and down buttons. I am currently able to get the similar desired effect of moving down the list with the tabindex attribute. I am also using ng repeat to generate the instances of the elements. Tips or clues on how to achieve being able to focus and scroll up and down the list by using the up and down keys?

Sample code below.

table ng-if="!toolbarCtrl.loadingContacts" class="table dataTable hover" id="table3">
                <tbody role="alert" aria-live="polite" aria-relevant="all">
                    <tr class="pointer" tabindex="0" ng-repeat="contact in toolbarCtrl.contactEntities | filter:toolbarCtrl.toolbarSearchStringAfterDelay | orderBy: toolbarCtrl.tab == toolbarCtrl.tabs.RECENT ? '-dateSeen' : (toolbarCtrl.tab == toolbarCtrl.tabs.ALL ? '+data.fileAs' : '')"
                        ng-class="" ng-if="toolbarCtrl.toolbarSearchStringAfterDelay" ng-click="toolbarCtrl.selectContact(contact)"> 
                        <td rel="popover_dark" ng-class="contact.loading ? 'contactDisabled' : '' " data-container="body" data-toggle="popover" data-placement="right" data-content="" data-original-title="" title="" class="sorting_1 has_popover">
                        </td>
                    </tr>
                </tbody>
            </table>

I mutated your checkKey function to bee this

 controller.checkKey = function (event) {
        $("tr[tabindex=0]").focus();
        var event = window.event;
        if (event.keyCode == 40) { //down
            var idx = $("tr:focus").attr("tabindex");
            idx++;
            if (idx > 6) {
                idx = 0;
            }
            $("tr[tabindex=" + idx + "]").focus();
        }
        if (event.keyCode == 38) { //up
            var idx = $("tr:focus").attr("tabindex");
            idx--;
            if (idx < 0) {
                idx = 6;
            }
            $("tr[tabindex=" + idx + "]").focus();
        }
    }

I'm close but its skipping straight to the last element. Does this look right?

Share Improve this question edited Jun 20, 2017 at 23:30 NVA asked Jun 20, 2017 at 18:41 NVANVA 1,6925 gold badges19 silver badges26 bronze badges 1
  • I can see why you're getting all tabindex="0" too...you're not using a variable for the tabindex value, you're assigning it to 0 every time. – mjw Commented Jun 21, 2017 at 16:10
Add a ment  | 

3 Answers 3

Reset to default 4

Here is a little technique for handling the keydown events for up/down arrows to navigate your table rows (<tr>). You may need to tweak the upper and lower tabindex handling from your generated data but that's on you. GL!

(jsfiddle: https://jsfiddle/qkna8jgu/2/ )

Sample HTML:

<table>
  <tr tabindex="0">
    <td>first row</td>
  </tr>
  <tr tabindex="1">
    <td>second row</td>
  </tr>
  <tr tabindex="2">
    <td>third row</td>
  </tr>
  <tr tabindex="3">
    <td>fourth row</td>
  </tr>
  <tr tabindex="4">
    <td>fifth row</td>
  </tr>
  <tr tabindex="5">
    <td>sixth row</td>
  </tr>
  <tr tabindex="6">
    <td>seventh row</td>
  </tr>
</table>

jQuery:

$(document).ready(function() {
    $("tr[tabindex=0]").focus();    
    document.onkeydown = checkKey;
});

function checkKey(e) {
    var event = window.event ? window.event : e;
    if(event.keyCode == 40){ //down
      var idx = $("tr:focus").attr("tabindex");
      idx++;
      if(idx > 6){
        idx = 0;
      }
      $("tr[tabindex="+idx+"]").focus();
    }
    if(event.keyCode == 38){ //up
      var idx = $("tr:focus").attr("tabindex");
      idx--;
      if(idx < 0){
        idx = 6;
      }
      $("tr[tabindex="+idx+"]").focus();      
    }
}

This was the approach that I used. It operates the jquery focus on a custom id that is created using the name and angular index. The preventDefault is merely because the up and down keys were also shifting my page up and down, this gets rid of that.

controller.checkKey = function (event, index) {
        event.preventDefault();
        if (event.keyCode === 40) {
            $('#item-' + (++index)).focus();
        }
        if (event.keyCode === 38) {
            $('#item-' + (--index)).focus();
        }
    };

This approach works well for angular paradigm and the jquery examples above are great too.

There's an easier way without using the indexes. You can merely use nextElementSibling and previousElementSibling. This example is adopted for selecting the table header instead. I'm just using plain ole JavaScript:

<!DOCTYPE html>
<html>
<body>
<table>
<thead>
    <tr>
        <th tabindex="0">Col 1</th>
        <th tabindex="1">Col 2</th>
    </tr>
</thead>
<tbody>
    <tr>
        <td>first row</td>
        <td>first row</td>
    </tr>
    <tr>
        <td>second row</td>
        <td>first row</td>
    </tr>
    <tr>
        <td>third row</td>
        <td>first row</td>
    </tr>
</tbody>
</table>
<script>
const d = document;
d.addEventListener("DOMContentLoaded", function() {

d.querySelector("th[tabindex='0']").focus();
  
d.addEventListener("keydown", function (event) {
    const t = event.target;
    const k = event.keyCode;
    if (k === 40) { //right
        const next = t.nextElementSibling;
        if (next) { next.focus(); }
    } else if (k === 38) { //left 
        const prev = t.previousElementSibling;
        if (prev) { prev.focus(); }
    }
});
});
</script>
</body>
</html>
发布评论

评论列表(0)

  1. 暂无评论