Files
blog/themes/Ying/assets/js/modules/search.js
T
2026-01-31 19:24:22 +08:00

197 lines
7.5 KiB
JavaScript

window.initSearch = function() {
initSearchModal();
initInlineSearch();
};
function loadSearchIndex() {
if (!window.searchIndex) {
return fetch('/index.json')
.then(response => response.json())
.then(data => {
window.searchIndex = data;
return data;
})
.catch(err => console.error('Failed to load search index:', err));
}
return Promise.resolve(window.searchIndex);
}
function initSearchModal() {
var searchBtn = document.getElementById('search-btn');
var searchModal = document.getElementById('search-modal');
if (searchBtn && searchModal) {
// Clone to remove old listeners
var newSearchBtn = searchBtn.cloneNode(true);
searchBtn.parentNode.replaceChild(newSearchBtn, searchBtn);
searchBtn = newSearchBtn;
searchBtn.addEventListener('click', function() {
searchModal.classList.add('show');
var input = document.getElementById('search-input');
if (input) setTimeout(function() { input.focus(); }, 100);
loadSearchIndex();
});
// Close logic
var closeBtn = searchModal.querySelector('.close-search');
if (closeBtn) {
closeBtn.onclick = function() {
searchModal.classList.remove('show');
};
}
// Click outside to close
searchModal.onclick = function(e) {
if (e.target === searchModal) {
searchModal.classList.remove('show');
}
};
// Search Input Logic
var searchInput = document.getElementById('search-input');
var searchResults = document.getElementById('search-results');
if (searchInput && searchResults) {
// Clone input to remove old listeners
var newInput = searchInput.cloneNode(true);
searchInput.parentNode.replaceChild(newInput, searchInput);
searchInput = newInput;
// Clone results to remove old listeners
var newResults = searchResults.cloneNode(true);
searchResults.parentNode.replaceChild(newResults, searchResults);
searchResults = newResults;
// Close modal when a result is clicked
searchResults.addEventListener('click', function(e) {
if (e.target.closest('a')) {
searchModal.classList.remove('show');
}
});
searchInput.addEventListener('input', function() {
var query = this.value.trim().toLowerCase();
if (!window.searchIndex || query.length === 0) {
searchResults.innerHTML = '<p class="search-tip">输入关键词并回车进行搜索</p>';
return;
}
var results = window.searchIndex.filter(function(item) {
return (item.title && item.title.toLowerCase().includes(query)) ||
(item.summary && item.summary.toLowerCase().includes(query));
});
if (results.length > 0) {
var html = results.map(function(item) {
return `
<div class="search-result-item">
<a href="${item.permalink}" class="search-result-title">${item.title}</a>
<span class="search-result-date">${item.date}</span>
<div class="search-result-summary">${item.summary || ''}</div>
</div>
`;
}).join('');
searchResults.innerHTML = html;
// Refresh PJAX to recognize new links
if (window.pjax) {
window.pjax.refresh(searchResults);
}
} else {
searchResults.innerHTML = '<p class="search-tip">未找到相关文章</p>';
}
});
}
}
}
function initInlineSearch() {
var header = document.getElementById('essay-header');
var searchContainer = document.getElementById('search-container');
var input = document.getElementById('inline-search-input');
var resultsContainer = document.getElementById('inline-search-results');
window.toggleSearchMode = function(show) {
if (!header || !searchContainer || !input || !resultsContainer) return;
if (show) {
header.style.display = 'none';
searchContainer.style.display = 'block';
input.focus();
loadSearchIndex();
} else {
header.style.display = 'inline-flex';
searchContainer.style.display = 'none';
input.value = '';
resultsContainer.classList.remove('show');
resultsContainer.innerHTML = '';
}
};
if (!header || !searchContainer || !input || !resultsContainer) return;
// Input Event
var newInput = input.cloneNode(true);
input.parentNode.replaceChild(newInput, input);
input = newInput;
input.addEventListener('input', function() {
var query = this.value.trim().toLowerCase();
if (query.length === 0) {
resultsContainer.classList.remove('show');
resultsContainer.innerHTML = '';
return;
}
if (!window.searchIndex) return;
var results = window.searchIndex.filter(function(item) {
return (item.title && item.title.toLowerCase().includes(query)) ||
(item.summary && item.summary.toLowerCase().includes(query));
});
if (results.length > 0) {
var html = results.slice(0, 5).map(function(item) {
return `
<a href="${item.permalink}" class="search-result-item" style="display:block; text-decoration:none;" onclick="window.toggleSearchMode(false)">
<span class="search-result-title">${item.title}</span>
<div style="display:flex; align-items:center;">
<span class="search-result-date">${item.date}</span>
</div>
</a>
`;
}).join('');
resultsContainer.innerHTML = html;
resultsContainer.classList.add('show');
// PJAX Refresh
if (window.pjax) {
window.pjax.refresh(resultsContainer);
}
} else {
resultsContainer.innerHTML = '<div class="search-result-item" style="text-align:center;color:#999;cursor:default;">无搜索结果</div>';
resultsContainer.classList.add('show');
}
});
// Close on click outside
if (!window.inlineSearchClickOutside) {
window.inlineSearchClickOutside = function(e) {
var header = document.getElementById('essay-header');
var searchContainer = document.getElementById('search-container');
var resultsContainer = document.getElementById('inline-search-results');
if (header && searchContainer && resultsContainer && searchContainer.style.display === 'block') {
if (!searchContainer.contains(e.target) && !header.contains(e.target) && !resultsContainer.contains(e.target)) {
window.toggleSearchMode(false);
}
}
};
document.addEventListener('click', window.inlineSearchClickOutside);
}
}