修复搜索无结果引导:改为浮动面板在搜索栏下方显示

This commit is contained in:
ZxR 2026-05-12 22:54:24 +08:00
parent da43a41102
commit 6494e4ac33
2 changed files with 63 additions and 72 deletions

View File

@ -44,6 +44,10 @@ html[data-theme=light] .menu{
html[data-theme='dark'] .docusaurus-highlight-code-line {
background-color: rgba(0, 0, 0, 0.3);
}
.navbar__search {
position: relative;
}
.navbar__search span[role='listbox']{
background-color: #33416b;
}
@ -152,16 +156,22 @@ html[data-theme='dark'] .docusaurus-highlight-code-line {
/* ===== 搜索无结果引导 ===== */
.search-no-result-guide {
margin-top: 16px;
padding: 14px 16px;
background: #f7f8fa;
border-radius: 8px;
position: absolute;
top: 100%;
left: 0;
right: 0;
margin-top: 6px;
padding: 16px 18px;
background: var(--search-local-modal-background, #fff);
border-radius: 10px;
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15);
z-index: 1000;
border: 1px solid #e5e7eb;
}
html[data-theme='dark'] .search-no-result-guide {
background: rgba(255, 255, 255, 0.06);
border-color: rgba(255, 255, 255, 0.1);
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);
}
.sr-guide-title {

View File

@ -2,6 +2,8 @@
'use strict';
var GUIDE_ID = 'search-no-result-guide';
var timer = null;
var lastValue = '';
function getLang() {
return (document.documentElement.lang || 'zh-CN').startsWith('en') ? 'en' : 'zh';
@ -15,7 +17,7 @@
if (lang === 'en') {
guide.innerHTML =
'<div class="sr-guide-title">Try these popular docs:</div>' +
'<div class="sr-guide-title">No results found. Try these popular docs:</div>' +
'<div class="sr-guide-chips">' +
'<a class="sr-guide-chip" href="/DevOps引擎/引擎简介">DevOps Pipeline</a>' +
'<a class="sr-guide-chip" href="/代码库管理/Webhook">Webhook</a>' +
@ -27,7 +29,7 @@
'</div>';
} else {
guide.innerHTML =
'<div class="sr-guide-title">试试浏览这些热门文档:</div>' +
'<div class="sr-guide-title">未找到结果,试试浏览热门文档:</div>' +
'<div class="sr-guide-chips">' +
'<a class="sr-guide-chip" href="/DevOps引擎/引擎简介">DevOps 流水线</a>' +
'<a class="sr-guide-chip" href="/代码库管理/Webhook">Webhook 配置</a>' +
@ -42,89 +44,68 @@
return guide;
}
function injectGuide(referenceNode) {
if (document.getElementById(GUIDE_ID)) return;
function removeGuide() {
var guide = document.getElementById(GUIDE_ID);
if (guide) guide.remove();
}
var container = referenceNode.closest('.navbar__search');
if (!container) return;
function hasVisibleResults() {
// 搜索下拉框有可见的 listbox 且包含子元素
var listbox = document.querySelector('.navbar__search span[role="listbox"]');
if (!listbox) return false;
if (listbox.offsetParent === null) return false;
var ul = listbox.querySelector('ul');
return ul && ul.children.length > 0;
}
// Find the search modal panel
var panel = container.querySelector('span[role="listbox"]');
if (!panel) {
// Try broader search
var existingGuide = container.querySelector('#' + GUIDE_ID);
if (existingGuide) existingGuide.remove();
function checkResults() {
var input = document.querySelector('.navbar__search input');
if (!input) return;
var currentValue = input.value.trim();
if (currentValue.length === 0) {
removeGuide();
return;
}
var text = panel.textContent || '';
var hasNoResults =
text.includes('没有结果') ||
text.includes('No results') ||
text.includes('未找到');
if (!hasNoResults) {
// Check if the list is truly empty
var list = panel.querySelector('ul, [role="list"]');
var hasItems = list && list.children.length > 0;
if (hasItems) {
var existingGuide = document.getElementById(GUIDE_ID);
if (existingGuide) existingGuide.remove();
return;
if (hasVisibleResults()) {
removeGuide();
} else {
// 没有可见结果,展示引导面板
if (!document.getElementById(GUIDE_ID)) {
var container = document.querySelector('.navbar__search');
if (container) {
var guide = createGuide();
container.appendChild(guide);
}
}
}
// Inject the guide
if (hasNoResults || (panel.children.length === 0 && text.trim().length > 0)) {
var guide = createGuide();
panel.appendChild(guide);
}
}
function onSearchInput(e) {
function onInput(e) {
var input = e.target;
if (!input.closest('.navbar__search')) return;
// Small delay to let the search results render
setTimeout(function () {
injectGuide(input);
}, 250);
clearTimeout(timer);
// 等搜索完成后再检查
timer = setTimeout(checkResults, 350);
}
function onSearchKeydown(e) {
if ((e.ctrlKey || e.metaKey) && e.key === 'k') {
// User opened search via Ctrl+K, observe for results
setTimeout(function () {
var input = document.querySelector('.navbar__search input');
if (input) {
// Watch for changes on this input
input.addEventListener('input', onSearchInput, { once: false });
injectGuide(input);
}
}, 500);
function onClickOutside(e) {
var guide = document.getElementById(GUIDE_ID);
if (!guide) return;
var searchContainer = document.querySelector('.navbar__search');
if (searchContainer && !searchContainer.contains(e.target)) {
removeGuide();
}
}
function init() {
document.addEventListener('input', onSearchInput, true);
document.addEventListener('keydown', onSearchKeydown, true);
// Also observe DOM for dynamically added search modal
var observer = new MutationObserver(function () {
var guide = document.getElementById(GUIDE_ID);
if (!guide) return;
// Check if search modal was removed
var inModal = guide.closest('.navbar__search');
if (!inModal) return;
// Check if results are now showing
var listbox = inModal.querySelector('span[role="listbox"]');
if (listbox) {
var list = listbox.querySelector('ul, [role="list"]');
if (list && list.children.length > 0) {
guide.remove();
}
}
document.addEventListener('input', onInput, true);
document.addEventListener('click', onClickOutside, true);
document.addEventListener('keydown', function (e) {
if (e.key === 'Escape') removeGuide();
});
observer.observe(document.body, { childList: true, subtree: true });
}
if (document.readyState === 'loading') {