spatial-navigation-polyfill
Version:
A polyfill for the spatial navigation
67 lines (61 loc) • 3.41 kB
HTML
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="application-name" content="Prevent 'navnotarget' Navigation Event">
<meta name="author" content="Jihye Hong">
<meta name="description" content="The 'navbeforefocus' event is fired when the next focus target is found.
If the event is prevented, the focus will not move to the found target.
The sample shows the <b>focus delegation</b> if the target is the scrollable spatial navigation container.
In that case, the focus will delegate to an element inside the container.">
<link rel="stylesheet" href="spatnav-style.css">
<script src="spatnav-utils.js"></script>
<script src="../../polyfill/spatial-navigation-polyfill.js"></script>
<link class="codestyle" rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js"></script>
</head>
<body>
<div class="container c1" id="scroller" tabindex="1" style="margin-left: 100px; width:200px; height: 200px; padding: 20px; overflow-x: scroll;">
<button class="box b2" style="top: 100px;"></button>
<button class="box b2" style="top: 100px; left: calc(100px * 1);"></button>
<button class="box b2" style="top: 100px; left: calc(100px * 2);"></button>
<button class="box b2" style="top: 100px; left: calc(100px * 3);"></button>
<button class="box b2" style="top: 100px; left: calc(100px * 4);"></button>
</div>
<button class="box b1" style="top: -120px; left: 50px;"></button>
<button class="box b1" style="top: 20px; left: 200px;"></button>
<button class="box b1" style="top: -130px; left: 350px;"></button>
<div class="event-log"></div>
</body>
<script type="text/javascript">
window.__spatialNavigation__.enableExperimentalAPIs(true);
const container = document.getElementById('scroller');
const logDiv = document.querySelector('.event-log');
let nextTarget = null;
container.addEventListener('navbeforefocus', (e) => {
appendLog('navbeforefocus', `*currentTarget: ${getElementInfoString(e.currentTarget)}, *target: ${getElementInfoString(e.target)}`);
let target = e.target;
// If the next focus target is the scrollable container, the focus delegates to an element inside it.
if (window.__spatialNavigation__.isContainer(target)) {
e.preventDefault();
const areas = target.focusableAreas({mode: 'visible'});
if (areas.length > 0) {
target = target.spatialNavigationSearch(e.detail.dir);
}
appendLog('navbeforefocus', `*Focus delegates from: ${getElementInfoString(e.target)} to: ${getElementInfoString(target)}`);
target.focus();
}
});
function getElementInfoString (element) {
return element.tagName + " " + element.className;
}
function appendLog (eventType, description) {
const newEventDiv = document.createElement('div');
newEventDiv.className = eventType;
newEventDiv.innerHTML = '<b>' + eventType + ' event! </b>' + description;
logDiv.appendChild(newEventDiv);
logDiv.scrollTop = logDiv.scrollHeight;
}
</script>
</html>