a11y & angularjs - windows 屏幕 reader 覆盖按键事件
a11y & angularjs - windows screen reader overrides keydown event
我正在努力使照片库应用程序更易于访问。
该应用程序具有在单击时显示图像展开视图的功能。
a11y 的要求之一是,当用户聚焦图像并单击进入时,展开模式将打开,焦点将进入展开视图内,并将设置在其中的一个按钮上。它在没有屏幕 reader 或 mac 上有屏幕 reader 的情况下工作正常。但是 windows
使用 screen reader 时,触发的代码似乎是订阅了点击事件而不是 keydown 事件的代码。因为假设在 keydown 上设置为 true 的标志是 false(两个事件都触发相同的功能,但 keydown 还添加了设置为 true 的 enterClicked 变量)。
这是持有图像并订阅事件的div:
<div
tabindex="0"
id="{{media.id}}"
data-ng-repeat="media in row track by media.id"
data-ng-mouseenter="events.toggleVideoPlay(media.type, media.id, media.link, ( rowNummer ) * (row.length) + ($index + 1))" class="imgContainer"
ng-keydown="$event.keyCode == 13 ? events.openExpandMode(media.id, true) : null"
data-ng-click="events.openExpandMode(media.id)"
>
openExpandMode 函数:
$scope.events.openExpandMode = (mediaId, isEnterClicked) => {
const state = {
isEnterClicked,
mediasId,
currentIndex,
pagination: $scope.mediasPagination,
settings: {
isUserName: $scope.settings.user_name_checkbox,
isTemplate: !$scope.userConnected && !$scope.userConnectedWithOldApi,
isLikeComments: $scope.settings.like_comments_checkbox,
isDescriptions: $scope.settings.description_checkbox,
isComments: $scope.settings.comments_checkbox,
theme: $scope.settings.expand_theme,
lang: $translate.use()
}
};
localStorageService.set('state', state);
}
扩展模式组件初始化:
const _init = () => {
if ($scope.isOpenFromEnter) {
document.getElementById('nextArrow').setAttribute('data-focus-visible-added', "");
document.getElementById('nextArrow').className += ' focus-visible';
document.getElementById('nextArrow').focus();
}
}
有没有办法停止windows屏幕reader事件拦截?
简答
发送点击事件而不是按下输入事件是很常见的。
最好的办法可能是调整您的代码,以便点击和输入做同样的事情,并且可以发送一个或两个事件,因为
您对发送或不发送的影响非常有限
更长的答案
您没有指明您使用的是哪个屏幕 reader(Jaws 或 NVDA),但无论如何,两者在按下 enter 时发送点击事件而不是发送键事件是很常见的。
乍一看,这样做的原因可能看起来很奇怪且不合逻辑,但至少有两个原因:
- 单击或按 Enter 时发生两种不同的事情当然是不合逻辑的。在 GUI 存在后的所有应用程序中,大多数情况下,两者都执行相同的操作(我现在能想到的唯一例外是多行或富文本字段)。
- Screen readers 在 web 可访问性之前就已经存在,而可访问性现在仍然很少实现。在按回车键时发送点击事件在设计人员甚至没有想到可以使用键盘代替鼠标的所有地方提供最小的可用性。
顺便问一下,屏幕 reader 与否,猜猜当焦点位于 link 或按钮上时按回车键会发送哪个事件?
据我所知,根据浏览器的不同,答案并不一致。
在屏幕 reader 方面,也不是一致的。有些甚至允许配置要采取的确切行为,以适应或多或少无法访问的不同站点。
is there a way to stop windows screen reader event interception ?
如果点击事件是由浏览器生成的,您可以通过在事件侦听器函数中调用 preventDefault 来停止某种形式的拦截。
通过这样做,您实际上可以在点击和输入时做一些不同的事情。但首先问问自己,这是否真的合理。想想我上面的第一点。
但是,您无法阻止屏幕 reader 拦截键盘事件,将它们转换为其他内容并发送或不发送到您的页面。
存在 ARIA 应用模式,但它有几个重要的含义,因此除非您有真正充分的理由,否则不应使用它。
总而言之,最好的办法可能是调整您的代码,以便点击和输入执行相同的操作,并且可以发送其中一个或两个事件。
将 role="application"
添加到容器 div
修复了它。
我正在努力使照片库应用程序更易于访问。
该应用程序具有在单击时显示图像展开视图的功能。
a11y 的要求之一是,当用户聚焦图像并单击进入时,展开模式将打开,焦点将进入展开视图内,并将设置在其中的一个按钮上。它在没有屏幕 reader 或 mac 上有屏幕 reader 的情况下工作正常。但是 windows 使用 screen reader 时,触发的代码似乎是订阅了点击事件而不是 keydown 事件的代码。因为假设在 keydown 上设置为 true 的标志是 false(两个事件都触发相同的功能,但 keydown 还添加了设置为 true 的 enterClicked 变量)。
这是持有图像并订阅事件的div:
<div
tabindex="0"
id="{{media.id}}"
data-ng-repeat="media in row track by media.id"
data-ng-mouseenter="events.toggleVideoPlay(media.type, media.id, media.link, ( rowNummer ) * (row.length) + ($index + 1))" class="imgContainer"
ng-keydown="$event.keyCode == 13 ? events.openExpandMode(media.id, true) : null"
data-ng-click="events.openExpandMode(media.id)"
>
openExpandMode 函数:
$scope.events.openExpandMode = (mediaId, isEnterClicked) => {
const state = {
isEnterClicked,
mediasId,
currentIndex,
pagination: $scope.mediasPagination,
settings: {
isUserName: $scope.settings.user_name_checkbox,
isTemplate: !$scope.userConnected && !$scope.userConnectedWithOldApi,
isLikeComments: $scope.settings.like_comments_checkbox,
isDescriptions: $scope.settings.description_checkbox,
isComments: $scope.settings.comments_checkbox,
theme: $scope.settings.expand_theme,
lang: $translate.use()
}
};
localStorageService.set('state', state);
}
扩展模式组件初始化:
const _init = () => {
if ($scope.isOpenFromEnter) {
document.getElementById('nextArrow').setAttribute('data-focus-visible-added', "");
document.getElementById('nextArrow').className += ' focus-visible';
document.getElementById('nextArrow').focus();
}
}
有没有办法停止windows屏幕reader事件拦截?
简答
发送点击事件而不是按下输入事件是很常见的。 最好的办法可能是调整您的代码,以便点击和输入做同样的事情,并且可以发送一个或两个事件,因为 您对发送或不发送的影响非常有限
更长的答案
您没有指明您使用的是哪个屏幕 reader(Jaws 或 NVDA),但无论如何,两者在按下 enter 时发送点击事件而不是发送键事件是很常见的。
乍一看,这样做的原因可能看起来很奇怪且不合逻辑,但至少有两个原因:
- 单击或按 Enter 时发生两种不同的事情当然是不合逻辑的。在 GUI 存在后的所有应用程序中,大多数情况下,两者都执行相同的操作(我现在能想到的唯一例外是多行或富文本字段)。
- Screen readers 在 web 可访问性之前就已经存在,而可访问性现在仍然很少实现。在按回车键时发送点击事件在设计人员甚至没有想到可以使用键盘代替鼠标的所有地方提供最小的可用性。
顺便问一下,屏幕 reader 与否,猜猜当焦点位于 link 或按钮上时按回车键会发送哪个事件? 据我所知,根据浏览器的不同,答案并不一致。 在屏幕 reader 方面,也不是一致的。有些甚至允许配置要采取的确切行为,以适应或多或少无法访问的不同站点。
is there a way to stop windows screen reader event interception ?
如果点击事件是由浏览器生成的,您可以通过在事件侦听器函数中调用 preventDefault 来停止某种形式的拦截。 通过这样做,您实际上可以在点击和输入时做一些不同的事情。但首先问问自己,这是否真的合理。想想我上面的第一点。
但是,您无法阻止屏幕 reader 拦截键盘事件,将它们转换为其他内容并发送或不发送到您的页面。 存在 ARIA 应用模式,但它有几个重要的含义,因此除非您有真正充分的理由,否则不应使用它。
总而言之,最好的办法可能是调整您的代码,以便点击和输入执行相同的操作,并且可以发送其中一个或两个事件。
将 role="application"
添加到容器 div
修复了它。