Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Preventing tab to cycle through address bar

I realize this is probably an accessibility issue that may best be left alone, but I'd like to figure out if it possible to prevent the tab from visiting the address bar in the tabbing cycle.

My application has another method of cycling through input areas, but many new users instinctively try to use the tab, and it doesn't work as expected.

like image 290
John Smith Avatar asked Mar 12 '13 07:03

John Smith


4 Answers

Here's a generic jquery implementation where you don't have to find the max tab index. Note that this code will also work if you add or remove elements in your DOM.

$('body').on('keydown', function (e) {
    var jqTarget = $(e.target);
    if (e.keyCode == 9) {

        var jqVisibleInputs = $(':input:visible');
        var jqFirst = jqVisibleInputs.first();
        var jqLast = jqVisibleInputs.last();

        if (!e.shiftKey && jqTarget.is(jqLast)) {
            e.preventDefault();
            jqFirst.focus();
        } else if (e.shiftKey && jqTarget.is(jqFirst)) {
            e.preventDefault();
            jqLast.focus();
        }
    }
});

However, you should note that the code above will work only with visible inputs. Some elements may become the document's activeElement even if they're not input so if it's your case, you should consider adding them to the $(':input:visible') selector.

I didn't add code to scroll to the focus element as this may not be the wanted behavior for everyone... if you need it, just add it after the call to focus()

like image 195
The_Black_Smurf Avatar answered Nov 20 '22 18:11

The_Black_Smurf


I used to add two tiny, invisible elements on tabindex 1 and on the last tabindex. Add a onFocus for these two: The element with tabindex 1 should focus the last real element, the one with the max tabindex should focus the first real element. Make sure that you focus the first real element on Dom:loaded.

like image 3
Jelmer Jellema Avatar answered Nov 20 '22 17:11

Jelmer Jellema


You can control the tabbing order (and which elements should be able to get focus at all) with the global tabindex attribute.

However, you can't prevent users to tab into another context not under control of the page (e.g. the browser's address bar) with this attribute. (It might be possible in combination with JavaScript, though.)

For such a (evil!) use case, you'd have to look into keyboard traps.

WCAG 2.0 has the guideline: 2.1.2 No Keyboard Trap. In Understanding SC 2.1.2 you can find "Techniques and Failures" for this guideline:

  • F10: Failure of Success Criterion 2.1.2 and Conformance Requirement 5 due to combining multiple content formats in a way that traps users inside one format type
  • FLASH17: Providing keyboard access to a Flash object and avoiding a keyboard trap
  • G21: Ensuring that users are not trapped in content

So maybe you get some ideas by that how such a trap would be possible.

like image 2
unor Avatar answered Nov 20 '22 19:11

unor


You could use Javascript and capture the "keydown" event on the element with the highest "tabindex". If the user presses the "TAB" key (event.keyCode==9) without the "Shift" key (event.shiftKey == false) then simply set the focus on the element with the lowest tabindex.

You would then also need to do the same thing in reverse for the element with the lowest tabindex. Capture the "keydown" event for this element. If the user presses the "TAB" key (event.keyCode==9) WITH the "Shift" key (event.shiftKey == true) then set the focus on the element with the highest tabindex.

This would effectively prevent the address bar from ever being focused using the TAB key. I am using this technique in my current project.

Dont forget to cancel the keydown event if the proper key-combination is pressed! With JQuery it's "event.preventDefault()". In standard Javascript, I believe you simply "return false".

Here's a JQuery-laden snippet I'm using...

    $('#dos-area [tabindex=' + maxTabIndex + ']').on('keydown', function (e) {
        if (e.keyCode == 9 && e.shiftKey == false) {
            e.preventDefault();
            $('#dos-area [tabindex=1]').focus();
        }
    });
    $('#dos-area [tabindex=1]').on('keydown', function (e) {
        if (e.keyCode == 9 && e.shiftKey == true) {
            e.preventDefault();
            $('#dos-area [tabindex=' + maxTabIndex + ']').focus();
        }
    });

Also keep in mind that setting tabindex=0 has undesirable results on the order in which things are focused. I always remember (for my purposes) that tabindex is a 1-based index.

like image 2
m-albert Avatar answered Nov 20 '22 19:11

m-albert