website: add search arrow selection.

This commit is contained in:
jaywcjlove 2022-11-22 00:18:06 +08:00
parent e0e7636ba4
commit b41c170b0c
2 changed files with 44 additions and 16 deletions

View File

@ -71,22 +71,47 @@ searchInput.addEventListener('input', (evn) => searchResult(evn.target.value));
let activeMenu = {} let activeMenu = {}
let result = [] let result = []
let inputValue = ''; let inputValue = '';
let activeIndex = 0
document.addEventListener('keydown', (ev) => { document.addEventListener('keydown', (ev) => {
console.log('ev::', ev)
if (ev.metaKey && ev.key.toLocaleLowerCase() === 'k') { if (ev.metaKey && ev.key.toLocaleLowerCase() === 'k') {
searchBox.classList.contains('show') ? hideSearch() : showSearch(); searchBox.classList.contains('show') ? hideSearch() : showSearch();
} }
if (ev.key.toLocaleLowerCase() === 'enter') { if (ev.key.toLocaleLowerCase() === 'enter') {
console.log('activeMenu:', activeMenu)
window.location.href = getDocUrl(activeMenu.path) window.location.href = getDocUrl(activeMenu.path)
} }
if (ev.key.toLocaleLowerCase() === 'arrowdown') {
activeAnchorElm('down')
}
if (ev.key.toLocaleLowerCase() === 'arrowup') {
activeAnchorElm('up')
}
}); });
function activeAnchorElm(type) {
if (type === 'down') {
++activeIndex;
}
if (type === 'up') {
--activeIndex;
}
const data = Array.from(searchMenu.children);
if (activeIndex < 0) activeIndex = 0;
if (activeIndex >= data.length) activeIndex = data.length - 1;
anchorElm = data[activeIndex];
if (anchorElm) {
data.forEach(item => item.classList.remove('active'));
anchorElm.classList.add('active');
activeMenu = result[activeIndex];
activeIndex = activeIndex;
searchSectionsResult(activeIndex);
}
}
function showSearch() { function showSearch() {
document.body.classList.add('search'); document.body.classList.add('search');
searchBox.classList.add('show'); searchBox.classList.add('show');
searchResult('') searchResult(searchInput.value || '');
searchInput.focus(); searchInput.focus();
} }
@ -107,13 +132,14 @@ function searchResult(value) {
let menuHTML = ''; let menuHTML = '';
result.forEach((item, idx) => { result.forEach((item, idx) => {
const label = item.item.name.replace(getValueReg(value), (txt) => { const label = item.item.name.replace(getValueReg(value), (txt) => {
return `<mark>${txt}</mark>` return `<mark>${txt}</mark>`;
}) })
const tags = (item.item.tags || []).join(',').replace(getValueReg(value), (txt) => { const tags = (item.item.tags || []).join(',').replace(getValueReg(value), (txt) => {
return `<mark>${txt}</mark>` return `<mark>${txt}</mark>`;
}) })
const href = isHome ? item.item.path : item.item.path.replace('docs/', ''); const href = isHome ? item.item.path : item.item.path.replace('docs/', '');
if (idx === 0) { if (idx === 0) {
activeIndex = idx;
activeMenu = item.item; activeMenu = item.item;
menuHTML += `<a href="${href}" class="active"><span>${label}</span><sup>${tags}</sup></a>`; menuHTML += `<a href="${href}" class="active"><span>${label}</span><sup>${tags}</sup></a>`;
} else { } else {
@ -122,12 +148,13 @@ function searchResult(value) {
}); });
searchMenu.innerHTML = menuHTML; searchMenu.innerHTML = menuHTML;
searchSectionsResult(); searchSectionsResult();
const data = Array.from(searchMenu.children) const data = Array.from(searchMenu.children);
data.forEach((anchor, idx) => { data.forEach((anchor, idx) => {
anchor.onmouseenter = (evn) => { anchor.onmouseenter = (evn) => {
data.forEach(item => item.classList.remove('active')); data.forEach(item => item.classList.remove('active'));
evn.target.classList.add('active'); evn.target.classList.add('active');
activeMenu = result[idx]; activeMenu = result[idx];
activeIndex = idx;
searchSectionsResult(idx); searchSectionsResult(idx);
} }
}); });
@ -138,23 +165,19 @@ function searchResult(value) {
} }
function searchSectionsResult(idx = 0) { function searchSectionsResult(idx = 0) {
const data = result[idx] || []; const data = result[idx] || [];
const title = (data.item?.intro || '').replace(getValueReg(inputValue), (txt) => { const title = (data.item?.intro || '').replace(getValueReg(inputValue), (txt) => `<mark>${txt}</mark>`);
return `<mark>${txt}</mark>`
});
let sectionHTML = `<h3>${title}</h3><ol>`; let sectionHTML = `<h3>${title}</h3><ol>`;
if (data && data.item && data.item.sections) { if (data && data.item && data.item.sections) {
data.item.sections.forEach((item, idx) => { data.item.sections.forEach((item, idx) => {
const label = item.t.replace(getValueReg(inputValue), (txt) => { const label = item.t.replace(getValueReg(inputValue), (txt) => `<mark>${txt}</mark>`);
return `<mark>${txt}</mark>`
})
const href = getDocUrl(data.item.path); const href = getDocUrl(data.item.path);
if (item.l < 3) { if (item.l < 3) {
sectionHTML += `<li><a href="${href + item.a}">${label}</a><div>` sectionHTML += `<li><a href="${href + item.a}">${label}</a><div>`;
} else { } else {
sectionHTML += `<a href="${href + item.a}">${label}</a>` sectionHTML += `<a href="${href + item.a}">${label}</a>`;
} }
if (data.item.sections.length === idx + 1) { if (data.item.sections.length === idx + 1) {
sectionHTML += `</div></li>` sectionHTML += `</div></li>`;
} }
}) })
} }

View File

@ -62,7 +62,12 @@ export function search({ homePath = '', isHome } = {}) {
{ {
type: 'element', type: 'element',
tagName: 'input', tagName: 'input',
properties: { id: ['mysearch-input'], type: 'search', placeholder: '搜索备忘清单' }, properties: {
id: ['mysearch-input'],
type: 'search',
placeholder: '搜索备忘清单',
autocomplete: 'off',
},
children: [], children: [],
}, },
{ {