通过选项卡结构使可点击的<div>可访问?

时间:2015-09-18 18:51:14

标签: html css accessibility wcag2.0

所以我正在开发一个需要<div> onclick事件的项目。我有主要功能,但有一个问题。当用户选中<div>并按Enter键时,我需要发生onclick事件。我在<div>添加了一个tabindex,它允许它获得焦点,但当用户按下enter(或任何其他键)时没有任何反应。

任何人都可以帮我吗?或者是我想要的甚至不可能?

这是一个证明我的问题的jsfiddle。 http://jsfiddle.net/logiwan992/suwq7r09/

提前感谢您的帮助。

5 个答案:

答案 0 :(得分:18)

我注意到问题标记为WCAG和&#34; accessibility&#34;。

因此,您的问题的答案是&#34;不要这样做。&#34;除了需要它工作的人,即那些使用屏幕阅读器或其他辅助技术的人之外,这个页面上的其他答案都可以正常工作。这里没有基于javascript的解决方案符合WCAG。

你想要的是<button>。这为您提供免费的tabindex和键盘控制。

您还可以通过添加ARIA标记强制<div><button>一样工作(尽管它更好,更容易使用已经完成您需要的标记的标记。)

如果绝对必要,可以在此处详细介绍如何使用ARIA进行伪按钮: https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Techniques/Using_the_button_role

要点是,您需要添加role="button"属性,并手动管理aria-pressed属性的状态(通过捕获javascript中的关键事件和点击;其他答案已经涵盖了这个漂亮的彻底,所以我不会重复细节)

答案 1 :(得分:3)

有一个&lt; div&gt;完全没问题。如果您指定了正确的ARIA标记,角色和键盘事件,则可以像按钮一样工作。这就是ARIA的重点。

我同意,如果可能的话,你应该使用原生的html元素。这是ARIA使用的第一条规则 - http://www.w3.org/TR/aria-in-html/#notes-on-aria-use-in-html。但我明白并非总是可行。

提到使用focus()。那是不对的。 Focus()用于将焦点移动到对象上。它不是用来处理事件的。现在也许他们的意思是onFocus(),这是一个在对象获得焦点时触发的事件,但这仍然不是陷阱的正确事件。您不希望按钮(无论是作为&lt; div&gt;还是&lt; button&gt;实现)才能执行其功能,因为您选中了它。用户必须单击或按下输入/空格。

请查看定义按钮键盘行为的创作实践http://www.w3.org/TR/wai-aria-practices/#button,以及讨论键盘事件的部分http://www.w3.org/TR/wai-aria-practices/#focus_tabindex。特别要注意的是,依赖于按键。并非所有浏览器都发送该事件。

无论何时按一个键,都会发生三个可能 的事件:Keydown,keypress,keyup。所有浏览器都支持Keydown和keyup,并且可以访问event.keyCode。某些浏览器支持Keypress,并且可以访问event.charCode。

keyCode和charCode之间存在显着差异,特别是如果您尝试实现Ctrl + /等快捷键。许多非美国键盘在键盘上的不同位置都有特殊键,您可以获得不同的键码。但这是另一个讨论的主题。

答案 2 :(得分:1)

“onclick”属性在链接上有特定的行为,因为它可以使用回车键触发。

请参阅以下WCAG失败: http://www.w3.org/TR/WCAG20-TECHS/F59.html

你必须照顾元素的“角色”。

以下页面说明了如何从“span”创建“可访问链接”: https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Techniques/Using_the_link_role

另外,正如已经说过的那样,最好的方法是尽可能依靠按钮/元素。

答案 3 :(得分:0)

尝试绑定上述char gridChar(int i) { switch(i) { case -1: return 'X'; case 0: return ' '; case 1: return 'O'; } } void draw(int b[9]) { printf(" %c | %c | %c\n",gridChar(b[0]),gridChar(b[1]),gridChar(b[2])); printf("---+---+---\n"); printf(" %c | %c | %c\n",gridChar(b[3]),gridChar(b[4]),gridChar(b[5])); printf("---+---+---\n"); printf(" %c | %c | %c\n",gridChar(b[6]),gridChar(b[7]),gridChar(b[8])); } int win(const int board[9]) { //determines if a player has won, returns 0 otherwise. unsigned wins[8][3] = {{0,1,2},{3,4,5},{6,7,8},{0,3,6},{1,4,7},{2,5,8},{0,4,8},{2,4,6}}; int i; for(i = 0; i < 8; ++i) { if(board[wins[i][0]] != 0 && board[wins[i][0]] == board[wins[i][1]] && board[wins[i][0]] == board[wins[i][2]]) return board[wins[i][2]]; } return 0; } int minimax(int board[9], int player) { //How is the position like for player (their turn) on board? int winner = win(board); if(winner != 0) return winner*player; move = -1; int score = -2;//Losing moves are preferred to no move int i; for(i = 0; i < 9; ++i) {//For all moves, if(board[i] == 0) {//If legal, board[i] = player;//Try the move int thisScore = -minimax(board, player*-1); if(thisScore > score) { score = thisScore; move = i; }//Pick the one that's worst for the opponent board[i] = 0;//Reset board after try } } if(move == -1) return 0; return score; } void computerMove(int board[9]) { int move = -1; int score = -2; int i; for(i = 0; i < 9; ++i) { if(board[i] == 0) { board[i] = 1; int tempScore = -minimax(board, -1); board[i] = 0; if(tempScore > score) { score = tempScore; move = i; } } } //returns a score based on minimax tree at a given node. board[move] = 1; } void playerMove(int board[9]) { int move = 0; do { printf("\nInput move ([0..8]): "); scanf("%d", &move); printf("\n"); } while (move >= 9 || move < 0 && board[move] == 0); board[move] = -1; } int main() { int board[9] = {0,0,0,0,0,0,0,0,0}; //computer squares are 1, player squares are -1. printf("Computer: O, You: X\nPlay (1)st or (2)nd? "); int player=0; scanf("%d",&player); printf("\n"); unsigned turn; for(turn = 0; turn < 9 && win(board) == 0; ++turn) { if((turn+player) % 2 == 0) computerMove(board); else { draw(board); playerMove(board); } } switch(win(board)) { case 0: printf("A draw. How droll.\n"); break; case 1: draw(board); printf("You lose.\n"); break; case -1: printf("You win. Inconceivable!\n"); break; } } 上的keypress事件并检测是否按下了div键(代码编号为Enter)。

13

Working JSFiddle

您也可以使用jQuery:

var div = document.getElementsByTagName('div');
div[0].addEventListener('keypress', function(e) {
    if(e.keyCode == 13) {
        alert('div focused');   
    }
});

Working JSFiddle

答案 4 :(得分:-2)

对两个事件使用相同的事件处理程序。如果事件为keypress,则在执行前确认按下的键是Enter键。

var divButton = document.querySelector('#div-button');

divButton.addEventListener('click', activate);
divButton.addEventListener('keypress', activate);

function activate(e) {
  if (e.type === 'keypress' && e.keyCode == 13) {
    alert('activated the div'); 
  }
};
div {
    outline: 1px solid black;
}

div:focus {
    outline: 1px solid red;
}
<div id="div-button" tabindex="0">
    <h1>This is my div!</h1>
</div>