feat: 将卡片悬浮提示固定在卡片下方或上方

This commit is contained in:
rbetree
2026-01-05 23:16:28 +08:00
parent 3e78332b54
commit 1d158aabd7

View File

@@ -2116,8 +2116,7 @@ document.addEventListener('DOMContentLoaded', () => {
// Tooltip functionality for truncated text仅桌面端/支持悬停设备启用) // Tooltip functionality for truncated text仅桌面端/支持悬停设备启用)
document.addEventListener('DOMContentLoaded', () => { document.addEventListener('DOMContentLoaded', () => {
const hoverMedia = const hoverMedia = window.matchMedia && window.matchMedia('(hover: hover) and (pointer: fine)');
window.matchMedia && window.matchMedia('(hover: hover) and (pointer: fine)');
if (!hoverMedia) { if (!hoverMedia) {
return; return;
@@ -2135,31 +2134,35 @@ document.addEventListener('DOMContentLoaded', () => {
let activeElement = null; let activeElement = null;
function updateTooltipPosition(e) { function updateTooltipPosition() {
// Position tooltip 15px below/right of cursor if (!activeElement) return;
const x = e.clientX + 15;
const y = e.clientY + 15; const rect = activeElement.getBoundingClientRect();
const tooltipRect = tooltip.getBoundingClientRect();
const gap = 10; // 卡片与Tooltip的间距
// 默认显示在卡片下方
let top = rect.bottom + gap;
// 水平居中对齐
let left = rect.left + (rect.width - tooltipRect.width) / 2;
// Boundary checks to keep inside viewport
const rect = tooltip.getBoundingClientRect();
const winWidth = window.innerWidth; const winWidth = window.innerWidth;
const winHeight = window.innerHeight; const winHeight = window.innerHeight;
let finalX = x; // 垂直边界检查:如果下方空间不足,尝试显示在上方
let finalY = y; if (top + tooltipRect.height > winHeight - gap) {
top = rect.top - tooltipRect.height - gap;
// If tooltip goes off right edge
if (x + rect.width > winWidth) {
finalX = e.clientX - rect.width - 10;
} }
// If tooltip goes off bottom edge // 水平边界检查:防止溢出屏幕左右边界
if (y + rect.height > winHeight) { if (left < gap) {
finalY = e.clientY - rect.height - 10; left = gap;
} else if (left + tooltipRect.width > winWidth - gap) {
left = winWidth - tooltipRect.width - gap;
} }
tooltip.style.left = finalX + 'px'; tooltip.style.left = left + 'px';
tooltip.style.top = finalY + 'px'; tooltip.style.top = top + 'px';
} }
// Show tooltip on hover // Show tooltip on hover
@@ -2173,13 +2176,8 @@ document.addEventListener('DOMContentLoaded', () => {
activeElement = target; activeElement = target;
tooltip.textContent = tooltipText; tooltip.textContent = tooltipText;
tooltip.classList.add('visible'); tooltip.classList.add('visible');
updateTooltipPosition(e); // 先显示元素让浏览器计算尺寸,然后立即更新位置
} updateTooltipPosition();
// Move tooltip with cursor
function onMouseMove(e) {
if (!activeElement) return;
updateTooltipPosition(e);
} }
// Hide tooltip on mouse out // Hide tooltip on mouse out
@@ -2195,12 +2193,10 @@ document.addEventListener('DOMContentLoaded', () => {
} }
document.addEventListener('mouseover', onMouseOver); document.addEventListener('mouseover', onMouseOver);
document.addEventListener('mousemove', onMouseMove);
document.addEventListener('mouseout', onMouseOut); document.addEventListener('mouseout', onMouseOut);
cleanupTooltip = () => { cleanupTooltip = () => {
document.removeEventListener('mouseover', onMouseOver); document.removeEventListener('mouseover', onMouseOver);
document.removeEventListener('mousemove', onMouseMove);
document.removeEventListener('mouseout', onMouseOut); document.removeEventListener('mouseout', onMouseOut);
activeElement = null; activeElement = null;