优化 职务图标显示

This commit is contained in:
2026-04-22 10:37:17 +08:00
parent fb96747352
commit 6c631aa495
3 changed files with 118 additions and 22 deletions
@@ -40,6 +40,8 @@
const BLOCKED_SYSTEM_SENDERS_STORAGE_KEY = 'chat_blocked_system_senders';
const CHAT_SOUND_MUTED_STORAGE_KEY = 'chat_sound_muted';
const BLOCKABLE_SYSTEM_SENDERS = ['钓鱼播报', '星海小博士', '百家乐', '跑马', '神秘箱子'];
const hoverTooltip = document.getElementById('chat-hover-tooltip');
let activeTooltipTrigger = null;
// ── 消息区:手机端双触发打开用户名片(PC 端靠 ondblclick 内联属性)──
// span[data-u] 由 clickableUser() 生成,touchend 委托至容器避免每条消息单独绑定
@@ -833,6 +835,105 @@
}
}
/**
* 把小气泡提示定位到图标旁边,不侵入右侧名单结构。
*
* @param {HTMLElement} trigger 当前悬浮的图标元素
*/
function positionHoverTooltip(trigger) {
if (!hoverTooltip || !trigger) {
return;
}
const offset = 10;
const rect = trigger.getBoundingClientRect();
const tooltipWidth = hoverTooltip.offsetWidth;
const tooltipHeight = hoverTooltip.offsetHeight;
const fitsRight = rect.right + offset + tooltipWidth <= window.innerWidth - 8;
const side = fitsRight ? 'right' : 'left';
const nextLeft = fitsRight
? rect.right + offset
: Math.max(8, rect.left - tooltipWidth - offset);
const nextTop = Math.min(
Math.max(8, rect.top + (rect.height - tooltipHeight) / 2),
window.innerHeight - tooltipHeight - 8
);
hoverTooltip.dataset.side = side;
hoverTooltip.style.left = `${nextLeft}px`;
hoverTooltip.style.top = `${nextTop}px`;
}
/**
* 显示图标旁边的小气泡文字提示。
*
* @param {HTMLElement|null} trigger 当前悬浮的图标元素
*/
function showHoverTooltip(trigger) {
if (!hoverTooltip || !trigger) {
return;
}
const tooltipText = trigger.dataset.instantTooltip || '';
if (!tooltipText) {
return;
}
activeTooltipTrigger = trigger;
hoverTooltip.textContent = tooltipText;
hoverTooltip.style.display = 'block';
positionHoverTooltip(trigger);
}
/**
* 隐藏图标提示气泡。
*/
function hideHoverTooltip() {
if (!hoverTooltip) {
return;
}
activeTooltipTrigger = null;
hoverTooltip.style.display = 'none';
hoverTooltip.textContent = '';
delete hoverTooltip.dataset.side;
}
// 通过事件委托处理动态生成的徽章提示,确保 hover 后立刻显示。
document.addEventListener('mouseover', (event) => {
const trigger = event.target.closest('.user-badge-icon[data-instant-tooltip]');
if (!trigger) {
return;
}
showHoverTooltip(trigger);
});
document.addEventListener('mouseout', (event) => {
const trigger = event.target.closest('.user-badge-icon[data-instant-tooltip]');
if (!trigger || trigger !== activeTooltipTrigger) {
return;
}
if (event.relatedTarget && trigger.contains(event.relatedTarget)) {
return;
}
hideHoverTooltip();
});
window.addEventListener('scroll', () => {
if (activeTooltipTrigger) {
positionHoverTooltip(activeTooltipTrigger);
}
}, true);
window.addEventListener('resize', () => {
if (activeTooltipTrigger) {
positionHoverTooltip(activeTooltipTrigger);
}
});
// ── 渲染在线人员列表(支持排序) ──────────────────
/**
* 核心渲染函数:将在线用户渲染到指定容器(桌面端名单区和手机端抽屉共用)