1

With links and form fields you can use tab to cycle trough and activate them.

In my code however I use lots of elements, that have an onclick attribute to perform different actions. For example a table, where each tr is clickable and expands on click.

Now I want my page to be browseable by keyboard only as well.

I was thinking about setting tabindex on each tr, which worked in Firefox (I was able to tab through the items, but not click them), but did not in Chrome.

How can I cycle through all elements containing onclick using the keyboard? If not with plain HTML, maybe with JQuery.

Lareau
  • 1,982
  • 1
  • 26
  • 47
JochenJung
  • 7,183
  • 12
  • 64
  • 113

7 Answers7

2

I'd recommend that you simply wrap the elements in anchor tags (<a>).

Sonny
  • 8,204
  • 7
  • 63
  • 134
1

Why not put a button on the row that will do the same action as the onclick of the row?

A button (or a link) will also get picked up by a screen reader.

Lareau
  • 1,982
  • 1
  • 26
  • 47
1

fiddle. Tabindex works in chrome 12 for me.

What's your actual problem?

Raynos
  • 166,823
  • 56
  • 351
  • 396
  • Funny you mention that works for me on 12.0.742.91 in chrome. (Check the console Ctrl+Shift+J and place focus on the iframe using a click to "bootstrap" it. It's not cheating because his page wont be in an iframe). Also this is win7 64bit – Raynos Jun 10 '11 at 14:42
  • Yes, checked that. Still not working. Also Win7 64 bit. Same (non)result in IE 9 and FF 4. Can't explain why it works for you and not for me. I'm clicking on "c1" and pressing the "Tab" key to try to set focus to "c2". – Craig Stuntz Jun 10 '11 at 14:53
  • @CraigStuntz you need to hit space when you have focus ;) It does allow you to tab and focus to them in IE9/FF4/Chrome. but then it tabs out into the jsfiddle interface. – Raynos Jun 10 '11 at 15:00
  • Indeed, it works in chrome and I like it, its simple. Had to modify your solution to not listen to input elements "if (e.target.nodeName != 'INPUT')", because I have an input field within the tr which in which I couldn't type spaces anymore. And I set all tabindex to "0" so they are just being added in order to the existing ones. – JochenJung Jun 10 '11 at 15:15
  • But maybe its not that browser safe... need to test it in some more browsers – JochenJung Jun 10 '11 at 15:15
  • @jochenjung for debugging purposes I recommend adding some key listener that colours the currently tabbed item. It does wonders. – Raynos Jun 10 '11 at 15:22
1

What you can possibly do, is keep track of the current element with onclick selected, and everytime the user hits - lets say the ~ button - it will move to the next one, and when he hits Enter - just trigger the .click(); for that element.

I've set up an example on jsfiddle: http://jsfiddle.net/dvirazulay/4kJnM/

This is sort of re-implementing tabindex, and you could do it better and change the actual selector to your liking...

Dvir
  • 5,049
  • 1
  • 23
  • 32
  • The visitor is usually not used to pressing ~ instead of tab. So I would prefer a way to make it work with tab. – JochenJung Jun 10 '11 at 15:18
  • @JochenJung: You could change it to use TAB instead, but the browsers tabbing functionality will mess everything up with it I believe. – Dvir Jun 10 '11 at 15:27
1

Something like this fiddle?

jQuery

var currentRow = -1;
$lastTd = jQuery();

$(document).keyup(function(event) {
    if ($.inArray([38, 40], event.keyCode)) {
        var $rows = $('table > tbody > tr');
        var newRow = currentRow + (event.keyCode == 40 ? 1 : -1);
        if (newRow > $rows.length - 1 || newRow < 0) return;
        
        currentRow = newRow;
        
        $lastTd.find('>div').hide();
        $lastTd.find('>span.indicator').remove();
        
        $lastTd = $rows.eq(currentRow)
                .find('>td')
                .prepend('<span class="indicator">&gt; </span>');
        
        // Show the content div
        $lastTd.find('div').fadeIn();
    }
});
Community
  • 1
  • 1
Gary Green
  • 22,045
  • 6
  • 49
  • 75
1

Using tabindex="0" allows you to navigate and move focus to the element/row with the tab-key. However, there is no way to trigger the onclick event by keyboard.

To overcome this, add an onkeydown event that triggers the onclick event:

<tr
  onclick="doYourStuff();"
  onkeydown="if(event.keyCode == 13 || event.keyCode == 32){event.target.click()}"
  tabindex="0">

You need to filter out other keypresses, except for space(32) and enter(13) when mimicing a click.

This listener would be better to put in a script rather than inline, but i'm just demonstrating the concept here.

lofihelsinki
  • 2,491
  • 2
  • 23
  • 35
0

I hope something like this might work for you, (it does not for me, i am poor at JS). You could edit it and you would get an invisible button filling the background of the table element and to tell the user which is selected you could have borders.

<!DOCTYPE HTML>
<html>
    <head>
        <title>Nav</title>
        <style>
            table#sample {
                border-width: 1px;
                border-spacing: 2px;
                border-style: outset;
                border-color: gray;
                border-collapse: separate;
                background-color: white;
            }
            table#sample th {
                border-width: 1px;
                padding: 1px;
                border-style: inset;
                border-color: gray;
                background-color: white;
                -moz-border-radius: ;
            }
            table#sample td {
                border-width: 1px;
                padding: 1px;
                border-style: inset;
                border-color: gray;
                background-color: white;
                -moz-border-radius: ;
            }

        </style>
    </head>
    <body>
        <table id="sample">
            <tr>
                <th>Sample</th>
                <th>Sample</th>
            </tr>
            <tr>
                <td ="section1">1</td>
                <td id="section2">2</td>
            </tr>
            <tr>
                <td id="section3">3</td>
                <td id="section4">4</td>
            </tr>
            <tr>
                <td id="section5">5</td>
                <td id="section6">6</td>
            </tr>
            <tr>
                <td id="section7">7</td>
                <td id="section8">8</td>
            </tr>
        </table>
        <script>
            var sec;
            var inside;
            for (var i=1; i < 9; i++) {
                sec = "section" + i;
                inside = "<input type='button' tabindex='" + i + "' />"
                document.getElementById(sec).innerHTML = inside;
            };
        </script>
    </body>
</html>
Rohan Verma
  • 447
  • 1
  • 4
  • 14