修复搜索判断逻辑:限定navbar范围并优先排除无结果文字
This commit is contained in:
parent
0f400d8214
commit
32280cd671
|
|
@ -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) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue