Files
docs.a2v.space/public/js/search.js
T
Агальцов Антон dd67d2c2ec Реструктуризация: два глобальных раздела — Яша и Семен
Весь контент перенесён в content/yasha/ (7 подразделов).
Создан content/semen/ с подразделами: changelog, kb, diary.
Навигация — dropdown в навбаре, двухуровневое меню в hugo.toml.
Шаблоны, сайдбар, поиск обновлены под вложенные секции.
2026-04-26 19:44:52 +03:00

96 lines
3.3 KiB
JavaScript

// Search functionality using Fuse.js
document.addEventListener('DOMContentLoaded', function() {
const searchInput = document.getElementById('search-input');
const searchForm = document.querySelector('.search-form');
const searchResults = document.getElementById('search-results');
const resultsList = document.getElementById('results-list');
const closeSearch = document.getElementById('close-search');
if (!searchInput) return;
let fuse;
// Load search index
fetch('/index.json')
.then(response => response.json())
.then(data => {
fuse = new Fuse(data, {
keys: ['title', 'content', 'tags'],
includeScore: true,
threshold: 0.3,
ignoreLocation: true,
minMatchCharLength: 2
});
})
.catch(err => console.error('Failed to load search index:', err));
function performSearch(query) {
if (!fuse || !query.trim()) {
searchResults.style.display = 'none';
return;
}
const results = fuse.search(query, { limit: 10 });
if (results.length === 0) {
resultsList.innerHTML = '<li>Ничего не найдено</li>';
} else {
resultsList.innerHTML = results.map(result => {
const item = result.item;
const sectionLabels = {
'yasha/diary': 'Яша / Дневник',
'yasha/kb': 'Яша / База знаний',
'yasha/plans': 'Яша / Планы',
'yasha/guides': 'Яша / Инструкции',
'yasha/creds': 'Яша / Креды',
'yasha/leadera': 'Яша / Leadera',
'yasha/personal-site': 'Яша / Личный сайт',
'semen': 'Семен',
'semen/diary': 'Семен / Дневник',
'semen/kb': 'Семен / База знаний'
};
const label = sectionLabels[item.section] || item.section;
return `<li>
<a href="${item.url}">
<strong>${item.title}</strong>
<small class="text-muted d-block">${label}</small>
</a>
</li>`;
}).join('');
}
searchResults.style.display = 'block';
}
// Debounce function
let debounceTimer;
function debounce(func, delay) {
return function() {
const context = this;
const args = arguments;
clearTimeout(debounceTimer);
debounceTimer = setTimeout(() => func.apply(context, args), delay);
};
}
searchInput.addEventListener('input', debounce(function(e) {
performSearch(e.target.value);
}, 200));
searchForm.addEventListener('submit', function(e) {
e.preventDefault();
performSearch(searchInput.value);
});
closeSearch.addEventListener('click', function() {
searchResults.style.display = 'none';
});
// Close search when clicking outside
document.addEventListener('click', function(e) {
if (!searchForm.contains(e.target) && !searchResults.contains(e.target)) {
searchResults.style.display = 'none';
}
});
});