inital setup
This commit is contained in:
		
							
								
								
									
										152
									
								
								assets/js/fastsearch.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										152
									
								
								assets/js/fastsearch.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,152 @@ | ||||
| import * as params from '@params'; | ||||
|  | ||||
| let fuse; // holds our search engine | ||||
| let resList = document.getElementById('searchResults'); | ||||
| let sInput = document.getElementById('searchInput'); | ||||
| let first, last, current_elem = null | ||||
| let resultsAvailable = false; | ||||
|  | ||||
| // load our search index | ||||
| window.onload = function () { | ||||
|     let xhr = new XMLHttpRequest(); | ||||
|     xhr.onreadystatechange = function () { | ||||
|         if (xhr.readyState === 4) { | ||||
|             if (xhr.status === 200) { | ||||
|                 let data = JSON.parse(xhr.responseText); | ||||
|                 if (data) { | ||||
|                     // fuse.js options; check fuse.js website for details | ||||
|                     let options = { | ||||
|                         distance: 100, | ||||
|                         threshold: 0.4, | ||||
|                         ignoreLocation: true, | ||||
|                         keys: [ | ||||
|                             'title', | ||||
|                             'permalink', | ||||
|                             'summary', | ||||
|                             'content' | ||||
|                         ] | ||||
|                     }; | ||||
|                     if (params.fuseOpts) { | ||||
|                         options = { | ||||
|                             isCaseSensitive: params.fuseOpts.iscasesensitive ?? false, | ||||
|                             includeScore: params.fuseOpts.includescore ?? false, | ||||
|                             includeMatches: params.fuseOpts.includematches ?? false, | ||||
|                             minMatchCharLength: params.fuseOpts.minmatchcharlength ?? 1, | ||||
|                             shouldSort: params.fuseOpts.shouldsort ?? true, | ||||
|                             findAllMatches: params.fuseOpts.findallmatches ?? false, | ||||
|                             keys: params.fuseOpts.keys ?? ['title', 'permalink', 'summary', 'content'], | ||||
|                             location: params.fuseOpts.location ?? 0, | ||||
|                             threshold: params.fuseOpts.threshold ?? 0.4, | ||||
|                             distance: params.fuseOpts.distance ?? 100, | ||||
|                             ignoreLocation: params.fuseOpts.ignorelocation ?? true | ||||
|                         } | ||||
|                     } | ||||
|                     fuse = new Fuse(data, options); // build the index from the json file | ||||
|                 } | ||||
|             } else { | ||||
|                 console.log(xhr.responseText); | ||||
|             } | ||||
|         } | ||||
|     }; | ||||
|     xhr.open('GET', "../index.json"); | ||||
|     xhr.send(); | ||||
| } | ||||
|  | ||||
| function activeToggle(ae) { | ||||
|     document.querySelectorAll('.focus').forEach(function (element) { | ||||
|         // rm focus class | ||||
|         element.classList.remove("focus") | ||||
|     }); | ||||
|     if (ae) { | ||||
|         ae.focus() | ||||
|         document.activeElement = current_elem = ae; | ||||
|         ae.parentElement.classList.add("focus") | ||||
|     } else { | ||||
|         document.activeElement.parentElement.classList.add("focus") | ||||
|     } | ||||
| } | ||||
|  | ||||
| function reset() { | ||||
|     resultsAvailable = false; | ||||
|     resList.innerHTML = sInput.value = ''; // clear inputbox and searchResults | ||||
|     sInput.focus(); // shift focus to input box | ||||
| } | ||||
|  | ||||
| // execute search as each character is typed | ||||
| sInput.onkeyup = function (e) { | ||||
|     // run a search query (for "term") every time a letter is typed | ||||
|     // in the search box | ||||
|     if (fuse) { | ||||
|         let results; | ||||
|         if (params.fuseOpts) { | ||||
|             results = fuse.search(this.value.trim(), {limit: params.fuseOpts.limit}); // the actual query being run using fuse.js along with options | ||||
|         } else { | ||||
|             results = fuse.search(this.value.trim()); // the actual query being run using fuse.js | ||||
|         } | ||||
|         if (results.length !== 0) { | ||||
|             // build our html if result exists | ||||
|             let resultSet = ''; // our results bucket | ||||
|  | ||||
|             for (let item in results) { | ||||
|                 resultSet += `<li class="post-entry"><header class="entry-header">${results[item].item.title} »</header>` + | ||||
|                     `<a href="${results[item].item.permalink}" aria-label="${results[item].item.title}"></a></li>` | ||||
|             } | ||||
|  | ||||
|             resList.innerHTML = resultSet; | ||||
|             resultsAvailable = true; | ||||
|             first = resList.firstChild; | ||||
|             last = resList.lastChild; | ||||
|         } else { | ||||
|             resultsAvailable = false; | ||||
|             resList.innerHTML = ''; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| sInput.addEventListener('search', function (e) { | ||||
|     // clicked on x | ||||
|     if (!this.value) reset() | ||||
| }) | ||||
|  | ||||
| // kb bindings | ||||
| document.onkeydown = function (e) { | ||||
|     let key = e.key; | ||||
|     let ae = document.activeElement; | ||||
|  | ||||
|     let inbox = document.getElementById("searchbox").contains(ae) | ||||
|  | ||||
|     if (ae === sInput) { | ||||
|         let elements = document.getElementsByClassName('focus'); | ||||
|         while (elements.length > 0) { | ||||
|             elements[0].classList.remove('focus'); | ||||
|         } | ||||
|     } else if (current_elem) ae = current_elem; | ||||
|  | ||||
|     if (key === "Escape") { | ||||
|         reset() | ||||
|     } else if (!resultsAvailable || !inbox) { | ||||
|         return | ||||
|     } else if (key === "ArrowDown") { | ||||
|         e.preventDefault(); | ||||
|         if (ae == sInput) { | ||||
|             // if the currently focused element is the search input, focus the <a> of first <li> | ||||
|             activeToggle(resList.firstChild.lastChild); | ||||
|         } else if (ae.parentElement != last) { | ||||
|             // if the currently focused element's parent is last, do nothing | ||||
|             // otherwise select the next search result | ||||
|             activeToggle(ae.parentElement.nextSibling.lastChild); | ||||
|         } | ||||
|     } else if (key === "ArrowUp") { | ||||
|         e.preventDefault(); | ||||
|         if (ae.parentElement == first) { | ||||
|             // if the currently focused element is first item, go to input box | ||||
|             activeToggle(sInput); | ||||
|         } else if (ae != sInput) { | ||||
|             // if the currently focused element is input box, do nothing | ||||
|             // otherwise select the previous search result | ||||
|             activeToggle(ae.parentElement.previousSibling.lastChild); | ||||
|         } | ||||
|     } else if (key === "ArrowRight") { | ||||
|         ae.click(); // click on active link | ||||
|     } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user