diff --git a/dist/focus-ring.js b/dist/focus-ring.js index e6b1a83..514380e 100644 --- a/dist/focus-ring.js +++ b/dist/focus-ring.js @@ -173,7 +173,6 @@ ClassList.prototype.toggle = function (token, force) { /* https://github.com/WICG/focus-ring */ document.addEventListener('DOMContentLoaded', function() { var hadKeyboardEvent = false; - var keyboardThrottleTimeoutID = 0; var elWithFocusRing; var inputTypesWhitelist = { @@ -224,7 +223,6 @@ document.addEventListener('DOMContentLoaded', function() { if (index(el).contains('focus-ring')) return; index(el).add('focus-ring'); - el.setAttribute('data-focus-ring-added', ''); // Keep a reference to the element to which the focus-ring class is applied // so the focus-ring class can be restored to it if the window regains // focus after being blurred. @@ -237,45 +235,39 @@ document.addEventListener('DOMContentLoaded', function() { * @param {Element} el */ function removeFocusRingClass(el) { - if (!el.hasAttribute('data-focus-ring-added')) - return; index(el).remove('focus-ring'); - el.removeAttribute('data-focus-ring-added'); } /** - * On `keydown`, set `hadKeyboardEvent`, to be removed 100ms later if there - * are no further keyboard events. The 100ms throttle handles cases where - * focus is redirected programmatically after a keyboard event, such as - * opening a menu or dialog. + * On `keydown`, set `hadKeyboardEvent`, add `focus-ring` class if the + * key was Tab. + * @param {Event} e */ - function onKeyDown() { - hadKeyboardEvent = true; + function onKeyDown(e) { + if (e.altKey || e.ctrlKey || e.metaKey) + return; - // `activeElement` defaults to document.body if nothing focused, - // so check the active element is actually focused. - var activeElement = document.activeElement; - if (activeElement.tagName == 'BODY') + if (e.keyCode != 9) return; - if (keyboardThrottleTimeoutID !== 0) - clearTimeout(keyboardThrottleTimeoutID); - keyboardThrottleTimeoutID = setTimeout(function() { - hadKeyboardEvent = false; - keyboardThrottleTimeoutID = 0; - }, 100); + hadKeyboardEvent = true; } /** * On `focus`, add the `focus-ring` class to the target if: - * - a keyboard event happened in the past 100ms, or - * - the focus event target triggers "keyboard modality" and should always - * have a focus ring drawn. + * - the target received focus as a result of keyboard navigation + * - the event target is an element that will likely require interaction + * via the keyboard (e.g. a text box) * @param {Event} e */ function onFocus(e) { - if (hadKeyboardEvent || focusTriggersKeyboardModality(e.target)) + if (e.target == document) + return; + + if (hadKeyboardEvent || focusTriggersKeyboardModality(e.target)) { addFocusRingClass(e.target); + hadKeyboardEvent = false; + } } /** @@ -283,6 +275,9 @@ document.addEventListener('DOMContentLoaded', function() { * @param {Event} e */ function onBlur(e) { + if (e.target == document) + return; + removeFocusRingClass(e.target); } @@ -291,14 +286,13 @@ document.addEventListener('DOMContentLoaded', function() { * to which it was previously applied. */ function onWindowFocus() { - if (document.activeElement == elWithFocusRing) { + if (document.activeElement == elWithFocusRing) addFocusRingClass(elWithFocusRing); - } } - document.body.addEventListener('keydown', onKeyDown, true); - document.body.addEventListener('focus', onFocus, true); - document.body.addEventListener('blur', onBlur, true); + document.addEventListener('keydown', onKeyDown, true); + document.addEventListener('focus', onFocus, true); + document.addEventListener('blur', onBlur, true); window.addEventListener('focus', onWindowFocus, true); }); diff --git a/src/focus-ring.js b/src/focus-ring.js index 9a41c28..407c7c3 100644 --- a/src/focus-ring.js +++ b/src/focus-ring.js @@ -3,7 +3,6 @@ import classList from 'dom-classlist'; /* https://github.com/WICG/focus-ring */ document.addEventListener('DOMContentLoaded', function() { var hadKeyboardEvent = false; - var keyboardThrottleTimeoutID = 0; var elWithFocusRing; var inputTypesWhitelist = { @@ -70,38 +69,35 @@ document.addEventListener('DOMContentLoaded', function() { } /** - * On `keydown`, set `hadKeyboardEvent`, to be removed 100ms later if there - * are no further keyboard events. The 100ms throttle handles cases where - * focus is redirected programmatically after a keyboard event, such as - * opening a menu or dialog. + * On `keydown`, set `hadKeyboardEvent`, add `focus-ring` class if the + * key was Tab. + * @param {Event} e */ - function onKeyDown() { - hadKeyboardEvent = true; + function onKeyDown(e) { + if (e.altKey || e.ctrlKey || e.metaKey) + return; - // `activeElement` defaults to document.body if nothing focused, - // so check the active element is actually focused. - var activeElement = document.activeElement; - if (activeElement.tagName == 'BODY') + if (e.keyCode != 9) return; - if (keyboardThrottleTimeoutID !== 0) - clearTimeout(keyboardThrottleTimeoutID); - keyboardThrottleTimeoutID = setTimeout(function() { - hadKeyboardEvent = false; - keyboardThrottleTimeoutID = 0; - }, 100); + hadKeyboardEvent = true; } /** * On `focus`, add the `focus-ring` class to the target if: - * - a keyboard event happened in the past 100ms, or - * - the focus event target triggers "keyboard modality" and should always - * have a focus ring drawn. + * - the target received focus as a result of keyboard navigation + * - the event target is an element that will likely require interaction + * via the keyboard (e.g. a text box) * @param {Event} e */ function onFocus(e) { - if (hadKeyboardEvent || focusTriggersKeyboardModality(e.target)) + if (e.target == document) + return; + + if (hadKeyboardEvent || focusTriggersKeyboardModality(e.target)) { addFocusRingClass(e.target); + hadKeyboardEvent = false; + } } /** @@ -109,6 +105,9 @@ document.addEventListener('DOMContentLoaded', function() { * @param {Event} e */ function onBlur(e) { + if (e.target == document) + return; + removeFocusRingClass(e.target); } @@ -117,13 +116,12 @@ document.addEventListener('DOMContentLoaded', function() { * to which it was previously applied. */ function onWindowFocus() { - if (document.activeElement == elWithFocusRing) { + if (document.activeElement == elWithFocusRing) addFocusRingClass(elWithFocusRing); - } } - document.body.addEventListener('keydown', onKeyDown, true); - document.body.addEventListener('focus', onFocus, true); - document.body.addEventListener('blur', onBlur, true); + document.addEventListener('keydown', onKeyDown, true); + document.addEventListener('focus', onFocus, true); + document.addEventListener('blur', onBlur, true); window.addEventListener('focus', onWindowFocus, true); });