HTML
<html>
<head>
<meta charset="utf-8">
<title></title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="main.css">
</head>
<body>
<div class="demo">
<div>
<label for="name">Name:</label>
<input type="text" id="name" name="name">
</div>
<h3>Drink Options</h3>
<ul id="group1" class="radiogroup">
<li class="radio">
Water
</li>
<li class="radio">
Tea
</li>
<li class="radio">
Coffee
</li>
<li class="radio">
Cola
</li>
<li class="radio">
Ginger Ale
</li>
</ul>
<div>
<button>Order a drink</button>
</div>
</div>
<script src="radiogroup.js"></script>
</body>
</html>
省略css,js是核心,以下为部分核心js代码
function RadioGroup(id) {
this.el = document.querySelector(id);
this.buttons = slice(this.el.querySelectorAll('.radio'));
this.focusedIdx = 0;
this.focusedButton = this.buttons[this.focusedIdx];
this.el.addEventListener('keydown', this.handleKeyDown.bind(this));
this.el.addEventListener('click', this.handleClick.bind(this));
// Set ARIA role for the radio group.
this.el.setAttribute('role', 'radiogroup');
var firstButton = true;
for (var button of this.buttons) {
if (firstButton) {
button.tabIndex = '0';
firstButton = false;
} else {
button.tabIndex = '-1';
}
// Set ARIA role for the radio.
button.setAttribute('role', 'radio');
}
}
上面为radiogroup和radio添加role
RadioGroup.prototype.handleKeyDown = function(e) {
switch(e.keyCode) {
case VK_UP:
case VK_LEFT: {
e.preventDefault();
this.focusedIdx--;
if (this.focusedIdx < 0)
this.focusedIdx = this.focusedIdx + this.buttons.length;
break;
}
case VK_DOWN:
case VK_RIGHT: {
e.preventDefault();
this.focusedIdx = (this.focusedIdx + 1) % this.buttons.length;
break;
}
case VK_SPACE:
var focusedButton = e.target;
var idx = this.buttons.indexOf(focusedButton);
if (idx < 0)
return;
this.focusedIdx = idx;
break;
default:
return;
}
this.changeFocus();
};
RadioGroup.prototype.handleClick = function(e) {
var button = e.target;
var idx = this.buttons.indexOf(button);
if (idx < 0)
return;
this.focusedIdx = idx;
this.changeFocus();
};
上为监听器函数
RadioGroup.prototype.changeFocus = function() {
// Set the old button to tabindex -1
this.focusedButton.tabIndex = -1;
this.focusedButton.removeAttribute('checked');
this.focusedButton.setAttribute('aria-checked', 'false');
// Set the new button to tabindex 0 and focus it
this.focusedButton = this.buttons[this.focusedIdx];
this.focusedButton.tabIndex = 0;
this.focusedButton.focus();
this.focusedButton.setAttribute('checked', '');
this.focusedButton.setAttribute('aria-checked', 'true');
};
var group1 = new RadioGroup('#group1');
}());
aria-checked这个属性不用初始化,可以在焦点改变时修改