JavaScript tooltip 位置限制在特定 div 内 - 优化代码实现
JavaScript tooltip 位置限制在特定 div 内 - 优化代码实现
本文将提供 JavaScript 代码优化方案,将 tooltip 的显示区域限制在指定的 div 元素内部,避免超出范围。
原代码:
let selectedLabel = null;
let currentTooltip = null;
let tooltipTimer = null;
labels.forEach((label) => {
label.addEventListener("mouseover", (e) => {
if (currentTooltip) {
document.querySelector(".category-options-wrapper").removeChild(currentTooltip);
clearTimeout(tooltipTimer);
}
const tooltip = document.createElement("div");
tooltip.classList.add("tooltip");
tooltip.innerHTML = label.getAttribute("data-title");
const imgSrc = label.getAttribute("data-img");
if (imgSrc) {
const img = new Image();
img.src = imgSrc;
img.onload = function() {
tooltip.appendChild(document.createElement('br'));
tooltip.appendChild(img);
}
img.onerror = function() {
console.log("Error: Failed to load image '" + imgSrc + "'");
left = e.pageX + 10;
top = e.pageY + 10;
tooltip.style.left = left + "px";
tooltip.style.top = top + "px";
}
}
tooltip.style.maxWidth = "300px";
document.querySelector(".category-options-wrapper").appendChild(tooltip);
const tooltipWidth = tooltip.offsetWidth;
const tooltipHeight = tooltip.offsetHeight;
const mouseX = e.clientX;
const mouseY = e.clientY;
const wrapperRect = document.querySelector(".category-options-wrapper").getBoundingClientRect();
let left = mouseX - wrapperRect.left + 10;
let top = mouseY - wrapperRect.top + 10;
if (!imgSrc) {
left = e.pageX + 10;
top = e.pageY + 10;
} else if (left + tooltipWidth > wrapperRect.left + wrapperRect.width) {
// tooltip 超出右侧边界
left = wrapperRect.left + wrapperRect.width - tooltipWidth;
}
if (top + tooltipHeight > wrapperRect.top + wrapperRect.height) {
// tooltip 超出下方边界
top = wrapperRect.top + wrapperRect.height - tooltipHeight;
}
tooltip.style.left = left + "px";
tooltip.style.top = top + "px";
tooltip.addEventListener("mousemove", () => {
clearTimeout(tooltipTimer);
});
tooltip.addEventListener("mouseout", () => {
tooltipTimer = setTimeout(() => {
document.querySelector(".category-options-wrapper").removeChild(tooltip);
currentTooltip = null;
// 如果该 label 元素是当前选中的元素,则不还原其背景颜色
if (label == selectedLabel) {
label.style.backgroundColor = "";
}
}, 5000);
});
currentTooltip = tooltip;
// 如果当前已有选中的 label 元素,则将其背景颜色还原
if (selectedLabel && label !== selectedLabel) {
selectedLabel.style.backgroundColor = "";
}
// 将当前 label 元素设置为选中,并将其背景颜色设置为 '#40b40d'
selectedLabel = label;
selectedLabel.style.backgroundColor = "rgba(64, 180, 13, 0.6)";
});
label.addEventListener("mouseleave", () => {
if (currentTooltip) {
tooltipTimer = setTimeout(() => {
document.querySelector(".category-options-wrapper").removeChild(currentTooltip);
currentTooltip = null;
// 如果该 label 元素是当前选中的元素,则不还原其背景颜色
if (label == selectedLabel) {
label.style.backgroundColor = "";
}
}, 2000);
}
});
});
优化后的代码:
const optionsRect = document.querySelector(".options").getBoundingClientRect();
// ...
let left = mouseX - optionsRect.left + 10;
let top = mouseY - optionsRect.top + 10;
if (!imgSrc) {
left = e.pageX + 10;
top = e.pageY + 10;
} else {
if (left + tooltipWidth > optionsRect.left + optionsRect.width) {
// tooltip 超出右侧边界
left = optionsRect.left + optionsRect.width - tooltipWidth;
}
if (top + tooltipHeight > optionsRect.top + optionsRect.height) {
// tooltip 超出下方边界
top = optionsRect.top + optionsRect.height - tooltipHeight;
}
}
// ...
currentTooltip = tooltip;
// ...
label.addEventListener("mouseleave", () => {
if (currentTooltip) {
tooltipTimer = setTimeout(() => {
document.querySelector(".options").removeChild(currentTooltip);
currentTooltip = null;
// 如果该 label 元素是当前选中的元素,则不还原其背景颜色
if (label == selectedLabel) {
label.style.backgroundColor = "";
}
}, 2000);
}
});
代码修改说明:
-
获取
optionsRect的方式:- 原代码使用
document.querySelector(".category-options-wrapper").getBoundingClientRect();获取category-options-wrapper元素的边界矩形。 - 修改后使用
document.querySelector(".options").getBoundingClientRect();获取options元素的边界矩形。
- 原代码使用
-
计算
tooltip位置的方式:- 原代码使用
wrapperRect计算tooltip的位置。 - 修改后使用
optionsRect计算tooltip的位置。
- 原代码使用
-
在
mouseleave事件中移除tooltip的父元素:- 原代码使用
document.querySelector(".category-options-wrapper").removeChild(currentTooltip);移除tooltip元素。 - 修改后使用
document.querySelector(".options").removeChild(currentTooltip);移除tooltip元素。
- 原代码使用
总结:
通过以上修改,代码将 tooltip 的显示区域限制在 options 元素内部,避免超出范围。修改后的代码更符合实际需求,并提供了更加精确的 tooltip 位置控制。
建议:
- 可以考虑使用 CSS 样式来控制 tooltip 的显示范围,例如设置
overflow: hidden属性。 - 可以使用 JavaScript 库来简化 tooltip 的实现,例如
popper.js。 - 可以根据实际需求调整 tooltip 的位置和显示方式。
原文地址: https://www.cveoy.top/t/topic/ofJC 著作权归作者所有。请勿转载和采集!