简体   繁体   English

覆盖默认选项卡行为以保持关注浏览器表单

[英]Override default Tab Behavior to keep focus on browser form

I'm building my first application where I have to have compliance with keyboard navigation for accessibility reasons.我正在构建我的第一个应用程序,出于可访问性的原因,我必须遵守键盘导航。

My problem has to do jquery-ui modal dialog boxes.我的问题必须做 jquery-ui 模态对话框。 If the user presses tab on the last control of the dialog (cancel button for this app), focus goes outside of the dialog box.如果用户在对话框的最后一个控件(此应用程序的取消按钮)上按下 Tab,焦点将移出对话框。 Or presses shift-tab on the first control in the dialog box.或者在对话框中的第一个控件上按下 shift-tab。

When the user does this, it isn't always possible to tab back into dialog box.当用户执行此操作时,并不总是可以用 Tab 键返回对话框。 IE8 and FF8 behave somewhat differently in this respect. IE8 和 FF8 在这方面的表现有些不同。 I've tried to capture the tab key with the following event handler -我尝试使用以下事件处理程序捕获制表键 -

lastButton.keydown(function (e) {
    if (e.which === TAB_KEY_CODE) {
        e.stopPropagation();
        $(this).focus();
    }
});

But this doesn't work as it appears the browser processes the key press after jquery is done.但这不起作用,因为浏览器在 jquery 完成后处理按键。

Two questions -两个问题——

  1. For Accessibility compliance, do I even have to worry about this?对于可访问性合规性,我什至不必担心这个吗? Although, for usability reasons, I think that I should.尽管出于可用性原因,我认为我应该这样做。
  2. Is there a way to make this work?有没有办法使这项工作?

My problem has to do jquery-ui modal dialog boxes.我的问题必须做 jquery-ui 模态对话框。 If the user presses tab on the last control of the dialog (cancel button for this app), focus goes outside of the dialog box.如果用户在对话框的最后一个控件(此应用程序的取消按钮)上按下 Tab,焦点将移出对话框。 Or presses shift-tab on the first control in the dialog box.或者在对话框中的第一个控件上按下 shift-tab。

... and then tabbing occurs below the modal box, under a grey semi-transparent layer with scrollbar jumping from bottom to top after a few keypresses? ...然后在模态框下方出现制表符,在灰色半透明层下,滚动条在几次按键后从底部跳到顶部? Yes, this is a concern for sighted users who use the keyboard to browse and won't know how to go back to the modal box without pressing Tab a hundred times.是的,对于使用键盘浏览并且不知道如何在不按 Tab 一百次的情况下返回模态框的视力正常的用户来说,这是一个问题。 Blind people won't even know the modal box is still displayed (they still can see/hear the entire DOM with their screen reader!) and that the page/script is waiting for a submit or cancel decision so it's also a concern for them.盲人甚至不知道模态框仍在显示(他们仍然可以使用屏幕阅读器看到/听到整个 DOM!)并且页面/脚本正在等待提交或取消决定,因此这也是他们关心的问题.

An example done right is shown at http://hanshillen.github.com/jqtest/#goto_dialog (click on Dialog tab, direct link with anchor doesn't work :/ ). http://hanshillen.github.com/jqtest/#goto_dialog显示了一个正确的示例(单击“对话框”选项卡,与锚点的直接链接不起作用:/)。 It'll tab forever inside the modal box till you click on Close or OK and will put you back on the focused element that triggered the modal box (I think it should focus the next focusable element after leaving the modal box but nevermind, this isn't the biggest accessibility problem here).它会永远在模态框内打标签,直到你点击关闭或确定,并将让你回到触发模态框的聚焦元素上(我认为它应该在离开模态框后聚焦下一个可聚焦元素,但没关系,这不是'不是这里最大的可访问性问题)。
This serie of scripts is based on jQueryUI and are highly improved for keyboard and ARIA support and any accessibility problem that could exist in the original scripts.这一系列脚本基于 jQueryUI,并针对键盘和 ARIA 支持以及原始脚本中可能存在的任何可访问性问题进行了高度改进。 Highly recommended!强烈推荐! (I tried to mix jQuery UI original scripts and these ones but didn't manage to get anything working, though you don't need to do so: these scripts work fine by themselves) (我尝试将 jQuery UI 原始脚本和这些脚本混合使用,但没有设法使任何工作正常运行,尽管您不需要这样做:这些脚本本身可以正常工作)

Im a little late to the party, but I found I had to call preventDefault in the other keyboard events as well.我参加聚会有点晚了,但我发现我也必须在其他键盘事件中调用 preventDefault。

ex) I was setting the focus in the keyup event.例如)我在 keyup 事件中设置焦点。 But the browser was still doing its thing in either keydown or keypress.但是浏览器仍然在用 keydown 或 keypress 做它的事情。 So I had something like this (I used JQuery/Typescript, but the idea should translate to about anything):所以我有这样的事情(我使用了 JQuery/Typescript,但这个想法应该可以转化为任何东西):

elem.keyup(this.onDialogKeyPress);
elem.keydown(this.onDialogPressPreventDefault);
elem.keypress(this.onDialogPressPreventDefault);

...

private onDialogPressPreventDefault = (e: KeyboardEvent) => {
    const keys = [9, 27];

    if (keys.includes(e.which)) {
        e.preventDefault();
        return false;
    }
}

private onDialogKeyPress = (e: KeyboardEvent) => {
    // Tab
    if (e.which == 9) {
        e.preventDefault();
        // Do tab stuff
        return false;
    }
    // Esc
    else if (e.which == 27) {
        e.preventDefault();
        // Do Esc stuff
        return false;
    }
}

Maybe you should prevent the default action with preventDefault() instead of stopping the propagation and use keypress instead of keydown.也许您应该使用preventDefault()来阻止默认操作,而不是停止传播并使用 keypress 而不是 keydown。
In this way there should be no need to regain focus.这样就不需要重新集中注意力。

Stopping the propagation doesn't work because it just prevent the event from bubbling up.停止传播不起作用,因为它只是防止事件冒泡。 You could think about using stopImmediatePropagation() but i think that changing input on the pression of the tab can't be stopped that way and preventDefault() is more correct.您可以考虑使用 stopImmediatePropagation() 但我认为无法通过这种方式停止更改按选项卡的输入,而 preventDefault() 更正确。

lastButton.keypress(function (e) {
    if (e.which === TAB_KEY_CODE) {
        e.preventDefault();
    }
});

fiddle here: http://jsfiddle.net/jfRzM/在这里小提琴: http : //jsfiddle.net/jfRzM/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM