修复搜索判断逻辑:限定navbar范围并优先排除无结果文字

This commit is contained in:
ZxR 2026-05-13 17:01:42 +08:00
parent 0f400d8214
commit 32280cd671
1 changed files with 42 additions and 49 deletions

View File

@ -4,8 +4,6 @@
var GUIDE_ID = 'search-no-result-guide'; var GUIDE_ID = 'search-no-result-guide';
var timer = null; var timer = null;
var pollTimer = null; var pollTimer = null;
var checkCount = 0;
var MAX_CHECKS = 6;
function getLang() { function getLang() {
return (document.documentElement.lang || 'zh-CN').startsWith('en') ? 'en' : 'zh'; return (document.documentElement.lang || 'zh-CN').startsWith('en') ? 'en' : 'zh';
@ -52,37 +50,49 @@
if (pollTimer) { clearInterval(pollTimer); pollTimer = null; } if (pollTimer) { clearInterval(pollTimer); pollTimer = null; }
} }
// 用 getBoundingClientRect 判断可见性,不受 position:absolute/fixed 影响
function isVisible(el) { function isVisible(el) {
if (!el) return false; if (!el) return false;
var r = el.getBoundingClientRect(); var r = el.getBoundingClientRect();
return r.width > 0 && r.height > 0; return r.width > 0 && r.height > 0;
} }
// 只检查 navbar 搜索区域内,有可见子项才算有结果
function hasVisibleResults() { function hasVisibleResults() {
// 全局搜索(搜索结果可能渲染在 portal 中,不一定在 .navbar__search 内) var searchEl = document.querySelector('.navbar__search');
var listbox = document.querySelector('[role="listbox"]'); if (!searchEl) return false;
if (listbox && isVisible(listbox)) {
var text = (listbox.textContent || '').trim(); var listbox = searchEl.querySelector('[role="listbox"]');
// 如果内容不为空且不是无结果提示 if (!listbox || !isVisible(listbox)) return false;
if (text.length > 0 &&
!text.includes('没有结果') && var text = (listbox.textContent || '').trim();
!text.includes('No results') &&
!text.includes('未找到')) { // 明确的无结果提示 → 没有结果
return true; if (text === '没有结果' || text === '没有结果:' ||
} text === 'No results' || text === '未找到结果') {
return false;
} }
// 检查所有可见的结果条目 // 有可见子元素li/a/按钮/div→ 有结果
var items = document.querySelectorAll('[role="option"], [role="listbox"] li, [role="listbox"] a'); var children = listbox.children;
for (var i = 0; i < items.length; i++) { for (var i = 0; i < children.length; i++) {
if (isVisible(items[i])) return true; if (isVisible(children[i])) return true;
}
// 没有可见子元素但有一行文字且不是无结果提示 → 可能是有结果
if (text.length > 0 && !text.startsWith('没有结果') && !text.startsWith('No results')) {
return true;
} }
return false; return false;
} }
function startPolling() { function showGuide() {
if (document.getElementById(GUIDE_ID)) return;
var container = document.querySelector('.navbar__search');
if (!container) return;
container.appendChild(createGuide());
// 轮询:结果出现时自动清除引导
if (pollTimer) clearInterval(pollTimer); if (pollTimer) clearInterval(pollTimer);
pollTimer = setInterval(function () { pollTimer = setInterval(function () {
var input = document.querySelector('.navbar__search input'); var input = document.querySelector('.navbar__search input');
@ -96,7 +106,7 @@
}, 300); }, 300);
} }
function showGuideIfNeeded() { function checkAndShow() {
var input = document.querySelector('.navbar__search input'); var input = document.querySelector('.navbar__search input');
if (!input) return; if (!input) return;
if (input.value.trim().length === 0) { if (input.value.trim().length === 0) {
@ -104,44 +114,27 @@
return; return;
} }
if (hasVisibleResults()) { // 延迟一小会等搜索渲染完再判断
removeGuide(); setTimeout(function () {
return; var curInput = document.querySelector('.navbar__search input');
} if (!curInput || curInput.value.trim().length === 0) {
removeGuide();
if (!document.getElementById(GUIDE_ID)) { return;
var container = document.querySelector('.navbar__search');
if (container) {
container.appendChild(createGuide());
} }
startPolling();
}
}
function checkWithRetry() { if (!hasVisibleResults()) {
checkCount = 0; showGuide();
removeGuide();
function doCheck() {
var input = document.querySelector('.navbar__search input');
if (!input || input.value.trim().length === 0) { removeGuide(); return; }
if (hasVisibleResults()) { return; }
checkCount++;
if (checkCount >= MAX_CHECKS) {
showGuideIfNeeded();
} else { } else {
setTimeout(doCheck, 200); removeGuide();
} }
} }, 500);
doCheck();
} }
function onInput(e) { function onInput(e) {
if (!e.target.closest('.navbar__search')) return; if (!e.target.closest('.navbar__search')) return;
removeGuide();
clearTimeout(timer); clearTimeout(timer);
timer = setTimeout(checkWithRetry, 300); timer = setTimeout(checkAndShow, 300);
} }
function onClickOutside(e) { function onClickOutside(e) {