(() => { fetch('/index.json') .then(response => response.json()) .then(data => { const fuse = new Fuse(data, { keys: ['title', 'content'], shouldSort: true, includeMatches: true, minMatchCharLength: 2, threshold: 0.0, ignoreLocation: true, }) document.getElementById('search-form').addEventListener('submit', function (e) { e.preventDefault(); const data = new FormData(e.target) // data.entries() returns iterator, [...data.entries()] returns [["q", "input"]] const input = [...data.entries()][0][1] const results = fuse.search(input) displayResults(input, results) }); }); })(); function displayResults(input, results) { const searchResults = document.getElementById('search-result'); searchResults.setAttribute('style', 'display: block;') searchResults.nextElementSibling.setAttribute('style', 'display: none;') let html = renderResultsCountHtml(results.length, input) if (results.length > 0) { let li = renderResultsItemHtml(results) html += `` } searchResults.innerHTML = html } function renderResultsCountHtml(count, input) { let html = `
${count} results for "${input}"
` return html } function renderResultsItemHtml(results) { // modified from https://github.com/brunocechet/Fuse.js-with-highlight var highlighter = function(resultItem){ resultItem.matches.forEach((matchItem) => { var text = resultItem.item[matchItem.key]; var result = [] var matches = [].concat(matchItem.indices); var pair = matches.shift() for (var i = 0; i < text.length; i++) { var char = text.charAt(i) if (pair && i == pair[0]) { result.push('') } result.push(char) if (pair && i == pair[1]) { result.push('') pair = matches.shift() } } resultItem.highlight = result.join(''); if(resultItem.children && resultItem.children.length > 0){ resultItem.children.forEach((child) => { highlighter(child); }); } }); }; let html = `` results.forEach(result => { highlighter(result) // truncated highlight content let truncated = result.highlight.substring(0, 2000) const reg = /([a-zA-Z0-9\u4e00-\u9fa5]+<\/span>)/g let array = truncated.split(reg) // drop unstable part array.pop() let content = "" if (array.length > 0) { content = array.join('') } else { // fallback to no highlighted truncated content content = result.item.content.substring(0, 2000) } html += `
  • ${content} ...
  • ` }) return html }