モーダルポップアップを開きました。アクセシビリティ要件があります。そこで、ARIA関連のラベルを追加しました。しかし、Tabキーをクリックすると、実際のページの後ろのページに移動し続けます。
htmlファイルにrole = "dialog"を追加
しかし、モーダルが開いたとき、私はフォーカスだけがモーダルポップアップ内をナビゲートしたいです。
取りかかっている Angular4, HTML5
事業。 HTMLファイル自体の中に解決策が見つかった方が良い。 これを防ぐためにjavascript/jQuery関連のものを追加しないことを意味します
あなたはフォーカストラップについて質問しています、それはこのデモでうまく示されています: http://davidtheclark.github.io/focus-trap/demo/
role="dialog"
を追加しても、その要素内にフォーカスをトラップすることは自動的には行われません。実際、ブラウザによって提供されるネイティブフォーカストラップなしがあります。
次のいずれかのオプションを選択する必要があります。
ただし、これは、 モーダルダイアログ内でフォーカスを維持する方法は? のような複数の質問ですでに示されているようなJavaScriptなしでは達成できません。
aria-hidden=true
を設定して、他のノードとのスクリーンリーダーの相互作用を無効にします例えば:
<main aria-hidden="true"><!-- main content here--></main>
<dialog>Your dialog here</dialog>
これは、Javascript /またはjQueryで実行する必要があります。
これは、jquery-uiを使用したjQueryのワンライナー命令です。
$("main :focusable").addClass("disabled").attr("tabindex", -1);
逆は、次を使用して実現できます。
$(".disabled").removeClass("disabled").attr("tabindex", 0);
cssサンプル:
main[aria-hidden='true'] { pointer-events: none;}
これが私の解決策です。モーダルダイアログの最初/最後の要素で必要に応じてTabまたはShift + Tabをトラップします(私の場合はrole="dialog"
で見つかります)。チェックされる適格な要素は、HTMLがinput,select,textarea,button
である可能性のあるすべての表示可能な入力コントロールです。
$(document).on('keydown', function(e) {
var target = e.target;
var shiftPressed = e.shiftKey;
// If TAB key pressed
if (e.keyCode == 9) {
// If inside a Modal dialog (determined by attribute role="dialog")
if ($(target).parents('[role=dialog]').length) {
// Find first or last input element in the dialog parent (depending on whether Shift was pressed).
// Input elements must be visible, and can be Input/Select/Button/Textarea.
var borderElem = shiftPressed ?
$(target).closest('[role=dialog]').find('input:visible,select:visible,button:visible,textarea:visible').first()
:
$(target).closest('[role=dialog]').find('input:visible,select:visible,button:visible,textarea:visible').last();
if ($(borderElem).length) {
if ($(target).is($(borderElem))) {
return false;
} else {
return true;
}
}
}
}
return true;
});
現在もAngular CDKは、モーダルポップアップにフォーカストラップを追加するディレクティブを提供しています https://material.angular.io/cdk/a11y/api#CdkTrapFocus
親ダイアログ要素には、これがダイアログであることを示すrole="dialog"
が必要です。あなたの場合、フォーカスがモーダル内にのみ留まるべきであることをブラウザとスクリーンリーダーに伝えるaria-modal="true"
もありません。
aria-modal="true"
を使用すると、スクリーンリーダーから非表示にし、モーダルが開いている間はモーダルの外側でキーボードフォーカスを受け取らないようにする必要がある要素に、aria-hidden="true"
を追加する必要がなくなります。
上記の方法が機能しない場合でも、キーボードがモーダルを離れないように、モーダルの外側の親要素にaria-hidden="true"
を使用することをお勧めします。
それでも機能せず、キーボードフォーカスを手動で制御する必要がある場合は、モーダル外でキーボードフォーカスを受け取る要素を確認してから、tabindex属性をtabindex="-1"
に設定できます。つまり、フォーカスを受け取ることはできますが、受け取ることはできません。キーボードから。このアプローチでは、モーダルが閉じたときに、これらの要素からtabindex="-1"
を削除するか、tabindex="0"
に戻すことで機能を復元する必要があるため、注意が必要です。
// place this line in the dialog show function - to only add the listener when the dialog is shown
window.addEventListener('keydown', handleKey);
// uncomment and place this in the dialog close/hide function to remove the listener when dialog is closed/hidden
// window.removeEventListener('keydown', handleKey);
function handleKey(e) {
if (e.keyCode === 9) {
let focusable = document.querySelector('#modal').querySelectorAll('input,button,select,textarea');
if (focusable.length) {
let first = focusable[0];
let last = focusable[focusable.length - 1];
let shift = e.shiftKey;
if (shift) {
if (e.target === first) { // shift-tab pressed on first input in dialog
last.focus();
e.preventDefault();
}
} else {
if (e.target === last) { // tab pressed on last input in dialog
first.focus();
e.preventDefault();
}
}
}
}
}