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