@@ -611,7 +611,8 @@ This event occurs when there is a valid result of <a>selecting the best candidat
611
611
<th> Attributes of the event
612
612
<td><dl>
613
613
<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
615
616
616
617
<dt> {{NavigationEvent}} .{{NavigationEvent/relatedTarget}}
617
618
<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
682
683
document.addEventListener('navbeforefocus' , e => {
683
684
e.preventDefault();
684
685
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();
688
689
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
+ }
692
693
}
693
- target .focus();
694
+ nextTarget .focus();
694
695
});
696
+
697
+ function isSpatialNavigationContainer(element) {
698
+ return (!element.parentElement) ||
699
+ (element.nodeName === 'IFRAME' ) ||
700
+ (isScrollContainer(element)) ||
701
+ (isCSSSpatNavContain(element));
702
+ }
695
703
</code></pre>
696
704
</div>
697
705
@@ -722,7 +730,8 @@ when it cannot be scrolled further.
722
730
<th> Attributes of the event
723
731
<td><dl>
724
732
<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
726
735
727
736
<dt> {{NavigationEvent}} .{{NavigationEvent/relatedTarget}}
728
737
<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
846
855
847
856
<div class=example id=loop>
848
857
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
851
860
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.
854
862
855
863
However, the focus can still be moved outside by sequential navigation,
856
864
mouse interaction,
857
865
or programmatic calls to {{focus()}} .
858
866
859
867
<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] ;
880
881
}
881
- } else {
882
- const target = container.spatialNavigationSearch(e.dir, { candidates: areas });
883
- target.focus();
882
+ nextTarget.focus();
884
883
}
885
884
});
886
885
</code></pre>
0 commit comments