JavaScript アクセシビリティ WAI-ARIAの基本2

キーボードのアクセシビリティをもっと拡張

キーボードのアクセシビリティを拡張するには、 tabindex 属性があります。 意味論的でない要素や正しい用途でないとき、 フォーカス可能にするために、 tabindex 属性により、 Tabキーが拡張され、 使えるようになります。 tabindex="0" 通常Tabキーで移動できない要素をタブ移動出来るようにします。 tabindex="-1" フォーカスを受け付けられるようになりますが、Tabキーは使用出来ません。 具体的な例としては次のようなコードがあります。

<h2>Fake buttons</h2> <div data-message="これは1番目のボタンです。" tabindex="0">クリック1</div> <div data-message="これは2番目のボタンです。" tabindex="0">クリック2</div> <div data-message="これは3番目のボタンです。" tabindex="0">クリック3</div> <script> const buttons = document.querySelectorAll('div'); for(let i = 0; i < buttons.length; i++) { addHandler(buttons[i]); } function addHandler(button) { button.onclick = function(e) { let message = e.target.getAttribute('data-message'); alert(message); } } document.onkeydown = function(e) { if(e.keyCode === 13) { // The Enter/Return key document.activeElement.onclick(e); } }; </script>

意味論的でないiコントロールのアクセシビリティ

フォームの場合で見ると、 アクセシビリティを良くするには、 次のような属性があります。 role="alert" aria-relevant="all" aria-required="true" などがあります。 role="alert" 属性は、 その要素が「警告メッセージ」であることを特定します。 aria-relevant="all" 属性は、 エラーが追加、削除されたとき、 エラーリスト(警告メッセージ)の内容をHTMLに表示し、 スクリーンリーダーが読み上げます。 aria-required="true" 属性は、 「入力が必須」であることを意味しています。 スクリーンリーダーは「入力が必須」であることを伝えます。 使用例は次の様になります。

<body> <h2>フォームバリデーションの例</h2> <div class="errors" role="alert" aria-relevant="all"> <ul> </ul> </div> <p>(*)のあるフィールドは必須です。</p> <form> <div> <label for="name">名前を入力*:</label> <input type="text" name="name" id="name" aria-required="true"> </div> <div> <label for="age">年齢を入力*:</label> <input type="number" name="age" id="age" placeholder="18才から60才まで" aria-required="true"> </div> <div> <input type="submit"> </div> <div></div> </form> <script> const inputs = document.querySelectorAll('input'); const labels = document.querySelectorAll('label'); const form = document.querySelector('form'); let formItems = []; const errorField = document.querySelector('.errors'); const errorList = document.querySelector('.errors ul'); for(let i = 0; i < inputs.length-1; i++) { let obj = {}; obj.label = labels[i]; obj.input = inputs[i]; formItems.push(obj); } errorField.style.left = '-100%'; form.onsubmit = validate; function validate(e) { errorList.innerHTML = ''; for(let i = 0; i < formItems.length; i++) { let testItem = formItems[i]; if(testItem.input.value === '') { errorField.style.left = '360px'; createLink(testItem); } }   if(errorList.innerHTML !== '') {  e.preventDefault();  } }    function createLink(testItem) { const listItem = document.createElement('li'); const anchor = document.createElement('a'); anchor.textContent = testItem.input.name + ' field is empty: fill in your ' + testItem.input.name + '.'; anchor.href = '#' + testItem.input.name; anchor.onclick = function() { testItem.input.focus(); }; listItem.appendChild(anchor); errorList.appendChild(listItem); }   </script> </body>

以上です。