Skip to content

Commit 3e8f5fa

Browse files
committed
Add keyboard navigation to search
1 parent 5c08d9f commit 3e8f5fa

File tree

1 file changed

+50
-6
lines changed

1 file changed

+50
-6
lines changed

src/js/07-search.js

Lines changed: 50 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,54 @@
44
function openSearchPopover () {
55
document.getElementById('search-background').style.display = 'block'
66
document.getElementById('search').style.display = 'block'
7+
78
// focus the textbox after popover appears
9+
focusSearchInput()
10+
// add eventlisteners after popover appears
11+
addNavigationToSearch()
12+
}
13+
14+
function closeSearchPopover () {
15+
document.getElementById('search-background').style.display = 'none'
16+
document.getElementById('search').style.display = 'none'
17+
}
18+
19+
function focusSearchInput () {
820
var searchInput = document.querySelector('.pagefind-modular-input')
921
if (searchInput) {
1022
searchInput.focus()
1123
}
1224
}
1325

14-
function closeSearchPopover () {
15-
document.getElementById('search-background').style.display = 'none'
16-
document.getElementById('search').style.display = 'none'
26+
function addNavigationToSearch () {
27+
// focus the first search result when pressing enter in search input
28+
document.getElementById('pfmod-input-0').addEventListener('keydown', goToSearchResultsOnEnter)
29+
}
30+
31+
function goToSearchResultsOnEnter (event) {
32+
var searchResults = document.getElementById('search-results')
33+
if (event.key === 'Enter' && searchResults.childElementCount > 0) {
34+
searchResults.firstChild.querySelector('a').focus()
35+
searchResults.addEventListener('keydown', addNavigationInSearchResults)
36+
}
37+
}
38+
39+
function addNavigationInSearchResults (event) {
40+
if (event.key === 'ArrowDown' && document.activeElement.classList.contains('pagefind-modular-list-link')) {
41+
event.preventDefault() // prevent page scrolling
42+
var nextSibling = document.activeElement.parentElement.parentElement.parentElement.nextElementSibling
43+
if (nextSibling) {
44+
nextSibling.querySelector('a').focus()
45+
}
46+
}
47+
48+
if (event.key === 'ArrowUp' && document.activeElement.classList.contains('pagefind-modular-list-link')) {
49+
event.preventDefault() // prevent page scrolling
50+
var previousSibling = document.activeElement.parentElement.parentElement.parentElement.previousElementSibling
51+
if (previousSibling) {
52+
previousSibling.querySelector('a').focus()
53+
}
54+
}
1755
}
1856

1957
// open the popover when clicking the magnifying glass search icon
@@ -28,20 +66,26 @@
2866
// close functionality when clicking the background
2967
var searchBackground = document.getElementById('search-background')
3068
if (searchBackground) {
31-
searchBackground.addEventListener('click', function (e) {
32-
e.stopPropagation() // trap event
69+
searchBackground.addEventListener('click', function (event) {
70+
event.stopPropagation() // trap event
3371
closeSearchPopover()
3472
})
3573
}
3674

37-
// open/close with keyboard
3875
document.addEventListener('keydown', function (event) {
76+
// open search with keyboard
3977
if (event.ctrlKey && event.key === 'k') {
4078
event.preventDefault() // prevent focussing the URL bar in the browser
4179
openSearchPopover()
4280
}
81+
// close search with keyboard
4382
if (event.key === 'Escape') {
4483
closeSearchPopover()
4584
}
85+
// focus the search input when pressing / while search popover is open
86+
if (event.key === '/') {
87+
event.preventDefault() // prevent opening the browser search dialog
88+
focusSearchInput()
89+
}
4690
})
4791
})()

0 commit comments

Comments
 (0)