@@ -611,7 +611,8 @@ This event occurs when there is a valid result of <a>selecting the best candidat
611611 <th> Attributes of the event
612612 <td><dl>
613613 <dt> {{Event}} .{{Event/target}}
614- <dd> The element receiving focus
614+ <dd> The focused element or if no element focused,
615+ then <a>the body element</a> if available, otherwise the root element
615616
616617 <dt> {{NavigationEvent}} .{{NavigationEvent/relatedTarget}}
617618 <dd> The DOM anchor of the focusable area that will be focused
@@ -682,16 +683,23 @@ the <a spec=html for="/">origin</a> of the [=active document=] of the [=top-leve
682683 document.addEventListener('navbeforefocus' , e => {
683684 e.preventDefault();
684685
685- let target = e.relatedTarget;
686- if (target.isSameNode(target.getSpatialNavigationContainer() )) {
687- const areas = target .focusableAreas();
686+ let nextTarget = e.relatedTarget;
687+ if (isSpatialNavigationContainer(nextTarget )) {
688+ const areas = nextTarget .focusableAreas();
688689
689- if (areas.length === 0) { break; }
690-
691- target = target.spatialNavigationSearch(e.dir, { candidates: areas });
690+ if (areas.length > 0) {
691+ nextTarget = nextTarget.spatialNavigationSearch(e.dir, { candidates: areas });
692+ }
692693 }
693- target .focus();
694+ nextTarget .focus();
694695 });
696+
697+ function isSpatialNavigationContainer(element) {
698+ return (!element.parentElement) ||
699+ (element.nodeName === 'IFRAME' ) ||
700+ (isScrollContainer(element)) ||
701+ (isCSSSpatNavContain(element));
702+ }
695703 </code></pre>
696704</div>
697705
@@ -722,7 +730,8 @@ when it cannot be scrolled further.
722730 <th> Attributes of the event
723731 <td><dl>
724732 <dt> {{Event}} .{{Event/target}}
725- <dd> The element receiving focus
733+ <dd> The focused element or if no element focused,
734+ then <a>the body element</a> if available, otherwise the root element
726735
727736 <dt> {{NavigationEvent}} .{{NavigationEvent/relatedTarget}}
728737 <dd> The <a>spatial navigation container</a> that was searched in.
@@ -846,41 +855,31 @@ the <a spec=html for="/">origin</a> of the [=active document=] of the [=top-leve
846855
847856<div class=example id=loop>
848857 The following code changes the behavior of spatial navigation
849- to trap the focus within a <a>spatial navigation container</a> :
850- when no further focusable elements can be found in the requested direction
858+ to trap the focus within a <a>spatial navigation container</a> which is vertically scrollable.
859+ When no further focusable elements can be found in the requested direction
851860 and the <a>spatial navigation container</a> cannot be scrolled any further,
852- the focus loops back to the other side instead of moving outside of it,
853- either by focusing or scrolling depending on what is available.
861+ the focus loops back to the other side instead of moving outside of it.
854862
855863 However, the focus can still be moved outside by sequential navigation,
856864 mouse interaction,
857865 or programmatic calls to {{focus()}} .
858866
859867 <pre><code highlight=javascript>
860- document.addEventListener('navnotarget' , e => {
861- e.preventDefault();
862-
863- const container = e.relatedTarget;
864- const areas = container.focusableAreas({ mode: 'all' });
865-
866- if (areas.length === 0) {
867- switch (e.dir) {
868- case 'down' :
869- container.scrollTop = 0;
870- break;
871- case 'up' :
872- container.scrollTop = container.scrollHeight;
873- break;
874- case 'right' :
875- container.scrollLeft = 0;
876- break;
877- case 'left' :
878- container.scrollLeft = container.scrollWidth;
879- break;
868+ scrollContainer.addEventListener('navnotarget' , e => {
869+ let nextTarget = null;
870+ const verticalDir = ['up', 'down'] ;
871+ const candidates = e.relatedTarget.focusableAreas({'mode' : 'all' });
872+
873+ // Prevent default only when navigation direction is on y-axis
874+ if (dirArray.includes(e.dir) && (candidates.length > 0)) {
875+ e.preventDefault();
876+
877+ if (e.dir === 'down' ) {
878+ nextTarget = candidates[0] ;
879+ } else if (e.dir === 'up' ) {
880+ nextTarget = candidates[candidates.length-1] ;
880881 }
881- } else {
882- const target = container.spatialNavigationSearch(e.dir, { candidates: areas });
883- target.focus();
882+ nextTarget.focus();
884883 }
885884 });
886885 </code></pre>
0 commit comments