mirror of
				https://github.com/Wonderfall/hugo-WonderMod.git
				synced 2025-10-31 03:45:24 +01:00 
			
		
		
		
	Search: Keyboard Bindings for easier navigation (#138)
* set up basic actions on keypress * add actions to perform conditionally * add simple highlight animation * prevent mouseclick to change active element * clear input box on Escape * click on Arrow Right * clear results and focus search-input on esc * refactor
This commit is contained in:
		| @@ -1,4 +1,4 @@ | |||||||
| .searchbox input { | #searchbox input { | ||||||
|     padding: 4px 10px; |     padding: 4px 10px; | ||||||
|     width: 100%; |     width: 100%; | ||||||
|     color: var(--primary); |     color: var(--primary); | ||||||
| @@ -7,7 +7,7 @@ | |||||||
|     border-radius: var(--radius); |     border-radius: var(--radius); | ||||||
| } | } | ||||||
|  |  | ||||||
| .searchbox input:focus { | #searchbox input:focus { | ||||||
|     border-color: var(--secondary); |     border-color: var(--secondary); | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -38,3 +38,7 @@ | |||||||
|     left: 0px; |     left: 0px; | ||||||
|     outline: none; |     outline: none; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | #searchResults .active { | ||||||
|  |     transform: scale(.98); | ||||||
|  | } | ||||||
|   | |||||||
| @@ -1,4 +1,8 @@ | |||||||
| var fuse; // holds our search engine | var fuse; // holds our search engine | ||||||
|  | var resList = document.getElementById('searchResults'); | ||||||
|  | var sInput = document.getElementById('searchInput'); | ||||||
|  | var first, last = null | ||||||
|  | var resultsAvailable = false; | ||||||
|  |  | ||||||
| // load our search index, only executed onload | // load our search index, only executed onload | ||||||
| function loadSearch() { | function loadSearch() { | ||||||
| @@ -35,6 +39,15 @@ function loadSearch() { | |||||||
|     xhr.send(); |     xhr.send(); | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | function itemGen(name, link) { | ||||||
|  |     return `<li class="post-entry"><header class="entry-header">${name} »</header><a href="${link}" aria-label="${name}"></a></li>` | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function activeToggle() { | ||||||
|  |     document.activeElement.parentElement.classList.toggle("active") | ||||||
|  | } | ||||||
|  |  | ||||||
| // execute search as each character is typed | // execute search as each character is typed | ||||||
| document.getElementById("searchInput").onkeyup = function (e) { | document.getElementById("searchInput").onkeyup = function (e) { | ||||||
|     // run a search query (for "term") every time a letter is typed |     // run a search query (for "term") every time a letter is typed | ||||||
| @@ -50,11 +63,60 @@ document.getElementById("searchInput").onkeyup = function (e) { | |||||||
|         } |         } | ||||||
|  |  | ||||||
|         document.getElementById("searchResults").innerHTML = resultSet; |         document.getElementById("searchResults").innerHTML = resultSet; | ||||||
|  |         resultsAvailable = true; | ||||||
|  |         first = resList.firstChild; | ||||||
|  |         last = resList.lastChild; | ||||||
|     } else { |     } else { | ||||||
|  |         resultsAvailable = false; | ||||||
|         document.getElementById("searchResults").innerHTML = ''; |         document.getElementById("searchResults").innerHTML = ''; | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| function itemGen(name, link) { | // kb bindings | ||||||
|     return `<li class="post-entry"><header class="entry-header">${name} »</header><a href="${link}" aria-label="${name}"></a></li>` | document.onkeydown = function (e) { | ||||||
|  |     let key = e.key; | ||||||
|  |     let ae = document.activeElement; | ||||||
|  |  | ||||||
|  |     if (key === "ArrowDown" && resultsAvailable) { | ||||||
|  |         e.preventDefault(); | ||||||
|  |         if (ae == sInput) { | ||||||
|  |             // if the currently focused element is the search input, focus the <a> of first <li> | ||||||
|  |             activeToggle(); // rm active class | ||||||
|  |             resList.firstChild.lastChild.focus(); | ||||||
|  |             activeToggle(); // add active class | ||||||
|  |         } else if (ae.parentElement == last) { | ||||||
|  |             // if the currently focused element's parent is last, do nothing | ||||||
|  |         } else { | ||||||
|  |             // otherwise select the next search result | ||||||
|  |             activeToggle(); // rm active class | ||||||
|  |             ae.parentElement.nextSibling.lastChild.focus(); | ||||||
|  |             activeToggle(); // add active class | ||||||
|  |         } | ||||||
|  |     } else if (key === "ArrowUp" && resultsAvailable) { | ||||||
|  |         e.preventDefault(); | ||||||
|  |         if (ae == sInput) { | ||||||
|  |             // if the currently focused element is input box, do nothing | ||||||
|  |         } else if (ae.parentElement == first) { | ||||||
|  |             // if the currently focused element is first item, go to input box | ||||||
|  |             activeToggle(); // rm active class | ||||||
|  |             sInput.focus(); | ||||||
|  |         } else { | ||||||
|  |             // otherwise select the previous search result | ||||||
|  |             activeToggle(); // rm active class | ||||||
|  |             ae.parentElement.previousSibling.lastChild.focus(); | ||||||
|  |             activeToggle(); // add active class | ||||||
|  |         } | ||||||
|  |     } else if (key === "ArrowRight" && resultsAvailable) { | ||||||
|  |         ae.click(); // click on active link | ||||||
|  |     } else if (key === "Escape") { | ||||||
|  |         resultsAvailable = false; | ||||||
|  |         document.getElementById("searchResults").innerHTML = sInput.value = ''; // clear inputbox and searchResults | ||||||
|  |         sInput.focus(); // shift focus to input box | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | document.onmousedown = function (e) { | ||||||
|  |     if (e.type === "mousedown") { | ||||||
|  |         e.preventDefault(); // prevent mousedown to change focus | ||||||
|  |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -30,7 +30,7 @@ | |||||||
|     {{- end}} |     {{- end}} | ||||||
| </header> | </header> | ||||||
|  |  | ||||||
| <div class="searchbox"> | <div id="searchbox"> | ||||||
|     <input id="searchInput" autofocus placeholder="{{.Title}} ↵" aria-label="search"> |     <input id="searchInput" autofocus placeholder="{{.Title}} ↵" aria-label="search"> | ||||||
|     <ul id="searchResults" aria-label="search results"></ul> |     <ul id="searchResults" aria-label="search results"></ul> | ||||||
| </div> | </div> | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Aditya Telange
					Aditya Telange