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

Override default Tab Behavior to keep focus on browser form

本文关键字:浏览器 表单 选项 默认 覆盖      更新时间:2023-09-26

我正在构建我的第一个应用程序,出于可访问性的原因,我必须遵守键盘导航。

我的问题必须做jquery-ui模态对话框。如果用户在对话框的最后一个控件上按下tab(此应用程序的取消按钮),焦点将移到对话框之外。或者按下对话框中第一个控件的shift键。

当用户这样做时,它并不总是能够回到对话框。IE8和FF8在这方面的表现有些不同。我尝试使用以下事件处理程序-

捕获制表键
lastButton.keydown(function (e) {
    if (e.which === TAB_KEY_CODE) {
        e.stopPropagation();
        $(this).focus();
    }
});

但这不起作用,因为浏览器似乎在jquery完成后才处理按键。

两个问题-

  1. 对于可访问性遵从性,我甚至需要担心这个吗?不过,出于可用性的考虑,我认为我应该这样做。
  2. 有办法让这个工作吗?

我的问题必须做jquery-ui模态对话框。如果用户在对话框的最后一个控件上按下tab(此应用程序的取消按钮),焦点将移到对话框之外。或者按下对话框中第一个控件的shift键。

…然后选项卡发生在模态框下面,在一个灰色的半透明层下,滚动条从底部跳到顶部,经过几个按键?是的,对于使用键盘浏览的正常用户来说,这是一个问题,他们不知道如何在不按Tab 100次的情况下返回模式框。盲人甚至不知道模式框仍然显示(他们仍然可以看到/听到整个DOM的屏幕阅读器!),页面/脚本正在等待提交或取消的决定,所以这也是他们关心的。

正确完成的示例显示在http://hanshillen.github.com/jqtest/#goto_dialog(单击对话框选项卡,直接链接与锚不起作用:/)。它将永远在模态框内分页,直到你点击关闭或确定,然后将你放回到触发模态框的焦点元素上(我认为它应该在离开模态框后聚焦下一个可聚焦元素,但没关系,这不是这里最大的可访问性问题)。这一系列脚本基于jQueryUI,并且对键盘和ARIA支持以及原始脚本中可能存在的任何可访问性问题进行了高度改进。强烈推荐!(我试图混合jQuery UI原始脚本和这些,但没有设法得到任何工作,虽然你不需要这样做:这些脚本工作很好自己)

也许你应该用preventDefault()来阻止默认动作,而不是停止传播,并使用keypress而不是keydown。
这样就不需要重新对焦了。

停止传播不起作用,因为它只是阻止事件冒泡。你可以考虑使用stopImmediatePropagation(),但我认为改变选项卡的输入不能停止的方式和preventDefault()是更正确的。

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

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

我有点晚了,但我发现我必须在其他键盘事件中调用preventDefault

ex)我在keyup事件中设置焦点。但浏览器仍然在按下键或按下键。所以我有这样的东西(我使用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;
    }
}