Support using keyboard to follow search results
This commit is contained in:
parent
056f1ddf72
commit
2939dfaf9c
3 changed files with 31 additions and 4 deletions
|
@ -45,9 +45,10 @@ function debouncer(interval, callback) {
|
||||||
}).then(result => {
|
}).then(result => {
|
||||||
while (results.lastChild) results.removeChild(results.lastChild);
|
while (results.lastChild) results.removeChild(results.lastChild);
|
||||||
|
|
||||||
result.hits.forEach(hit => {
|
result.hits.forEach((hit, index) => {
|
||||||
const item = resultPrototype.cloneNode(true);
|
const item = resultPrototype.cloneNode(true);
|
||||||
item.querySelector('.link').href = hit.slug || ".";
|
item.querySelector('.link').href = hit.slug || ".";
|
||||||
|
item.querySelector('.link').setAttribute("data-focusindex", index + 1);
|
||||||
item.querySelector('.title').textContent = hit.title;
|
item.querySelector('.title').textContent = hit.title;
|
||||||
item.querySelector('.snippet').textContent = hit.snippet;
|
item.querySelector('.snippet').textContent = hit.snippet;
|
||||||
results.appendChild(item);
|
results.appendChild(item);
|
||||||
|
@ -71,4 +72,26 @@ function debouncer(interval, callback) {
|
||||||
// We are now actually losing focus from the form:
|
// We are now actually losing focus from the form:
|
||||||
form.classList.remove("focus");
|
form.classList.remove("focus");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function moveFocus(delta) {
|
||||||
|
const focusIndexText = document.activeElement.getAttribute("data-focusindex");
|
||||||
|
if (!focusIndexText) return;
|
||||||
|
const currentIndex = parseInt(focusIndexText, 10);
|
||||||
|
const nextIndex = currentIndex + delta;
|
||||||
|
|
||||||
|
const candidate = form.querySelector("[data-focusindex=\"" + nextIndex + "\"]");
|
||||||
|
if (candidate) candidate.focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
form.addEventListener('keydown', function (ev) {
|
||||||
|
if (ev.key === 'ArrowUp') {
|
||||||
|
ev.preventDefault();
|
||||||
|
ev.stopPropagation();
|
||||||
|
moveFocus(-1);
|
||||||
|
} else if (ev.key === 'ArrowDown') {
|
||||||
|
ev.preventDefault();
|
||||||
|
ev.stopPropagation();
|
||||||
|
moveFocus(1);
|
||||||
|
}
|
||||||
|
});
|
||||||
})();
|
})();
|
||||||
|
|
|
@ -361,11 +361,15 @@ article ul.search-results {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
padding: 8px;
|
padding: 8px;
|
||||||
}
|
}
|
||||||
.live-results .search-result a:hover {
|
.live-results .search-result a:hover, .live-results .search-result a:focus {
|
||||||
background: #0074D9;
|
background: #0074D9;
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.live-results .search-result .title {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
.prototype {
|
.prototype {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,11 +9,11 @@
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<form class=search action=_search method=GET>
|
<form class=search action=_search method=GET>
|
||||||
<input type=search name=q placeholder=search autocomplete=off>
|
<input data-focusindex="0" type=search name=q placeholder=search autocomplete=off>
|
||||||
<ul class="live-results search-results">
|
<ul class="live-results search-results">
|
||||||
</ul>
|
</ul>
|
||||||
</form>
|
</form>
|
||||||
<ul id="search-result-prototype" class="prototype"><li class="search-result" tabindex="0"><a class="link" href=""><span class="title"></span> – <span class="snippet"></span></a></li></ul>
|
<ul id="search-result-prototype" class="prototype"><li class="search-result"><a class="link" href=""><span class="title"></span> – <span class="snippet"></span></a></li></ul>
|
||||||
<script src="_assets/search-{{search_js_checksum()}}.js" defer></script>
|
<script src="_assets/search-{{search_js_checksum()}}.js" defer></script>
|
||||||
{{{body}}}
|
{{{body}}}
|
||||||
</body>
|
</body>
|
||||||
|
|
Loading…
Reference in a new issue