spatial-navigation-polyfill
Version:
A polyfill for the spatial navigation
67 lines (61 loc) • 3.37 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 'navnotarget' event is fired when the focus reaches to the end of the scrollable element(container),
and the focus will move out of the container. If the event is prevented, the focus will remain in the container.
The sample shows the <b>focus looping</b> in the scrollable spatial navigation 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">
const container = document.getElementById('scroller');
const logDiv = document.querySelector('.event-log');
const dirArray = ['left', 'right'];
let nextTarget = null;
container.addEventListener('navnotarget', function(e) {
appendLog('navnotarget', `*currentTarget: ${getElementInfoString(e.currentTarget)}, *target: ${getElementInfoString(e.target)}`);
const candidates = e.target.focusableAreas({'mode': 'all'});
// Prevent default only when navigation direction is on x-axis
if (dirArray.includes(e.detail.dir) && (candidates.length > 0)) {
e.preventDefault();
appendLog('navnotarget', `is cancelled when the navigation direction is <i>${e.detail.dir}</i>`);
if (e.detail.dir === 'right') {
nextTarget = candidates[0];
} else if (e.detail.dir === 'left') {
nextTarget = candidates[candidates.length-1];
}
nextTarget.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>