我有一个元素,当鼠标悬停时,我会显示附加信息
document.getElementById(item.id).getElementsByTagName("div")[0].classList.add(classes.hoverDescription)
.treeNodeDescription{
font-family: "liberation-sans", sans-serif;
font-weight: 400;
font-style: normal;
font-size: 13px;
padding: 5px;
background-color: #333333;
color: #F8F7F7;
padding: 10px;
border-radius: 10px;
display: none;
position: absolute;
top: 130%;
left: 21%;
z-index: 10;
max-width: 300px;
text-wrap: wrap;
}
.hoverDescription{
display: block;
}
但我想在 3 秒等待时间后显示工具提示。并在鼠标离开时将其隐藏。
如何使用 JavaScript 或 CSS 来做到这一点?
我会建议一个CSS解决方案,因为:JavaScript不是必需的。
要在悬停时显示工具提示,只需使用
:hover
。对于出现的延迟,您可以使用 CSS 的 delay
值 animation
。style="--delay:3sec;"
- 自定义必要的延迟:
.tooltip{
position: absolute;
z-index: 10;
font: 13px/1.4 "liberation-sans", sans-serif;
padding: 10px;
border-radius: 10px;
top: calc(100% + 0.5em);
left: 50%;
translate: -50% 0;
max-width: 300px;
opacity: 0;
pointer-events: none;
background-color: #333333;
color: #F8F7F7;
}
:has(> .tooltip) {
position: relative;
color: fuchsia;
&:hover .tooltip {
animation: tooltip 0.3s var(--delay, 0s) forwards;
}
}
@keyframes tooltip {
100% { opacity: 1; }
}
<p>
Lorem ipsum
<span>Hover me for 3 sec <span class="tooltip" style="--delay:3s;">This is a description</span></span>
dolor sit amet. Consectetur adipisicing elit. Provident asperiores,
<span>And me for 1 sec<span class="tooltip" style="--delay:1s;">Just another description</span></span>
odio vel assumenda quasi. <span>Hover me too!<span class="tooltip">No delay! Yay!</span></span>
stahit overflavis.
</p>
提示:使用等待加载程序可以获得更好的用户体验?
为什么不呢,将
style="--delay:3s;"
移动到父元素,并为加载器添加一个 ::before
伪元素:
.tooltip {
position: absolute;
z-index: 10;
font: 13px/1.4 "liberation-sans", sans-serif;
padding: 10px;
border-radius: 10px;
top: calc(100% + 0.5em);
left: 50%;
translate: -50% 0;
max-width: 300px;
opacity: 0;
pointer-events: none;
background-color: #333333;
color: #F8F7F7;
}
:has(> .tooltip) {
position: relative;
color: fuchsia;
white-space: nowrap;
cursor: help;
&::before {
content: "";
position: absolute;
top: 100%;
background: currentColor;
height: 2px;
width: 0%;
}
&:hover {
&::before {
animation: tooltipLoader var(--delay, 0s) 0s linear forwards;
}
.tooltip {
animation: tooltip 0.3s var(--delay, 0s) forwards;
}
}
}
@keyframes tooltip {
100% { opacity: 1; }
}
@keyframes tooltipLoader {
100% { width: 100%; }
}
<p>
Lorem ipsum
<span style="--delay:3s;">Hover me for 3 sec <span class="tooltip">This is a description</span></span>
dolor sit amet. Consectetur adipisicing elit. Provident asperiores,
<span style="--delay:1s;">And me for 1 sec<span class="tooltip">Just another description</span></span>
odio vel assumenda quasi. <span>Hover me too!<span class="tooltip">No delay! Yay!</span></span>
stahit overflavis.
</p>
请将此脚本标签插入您的 html 文件中。
<script>
const item = document.getElementById(item.id);
const description = item.getElementsByTagName('div')[0];
let hoverTimeout;
item.addEventListener('mouseenter', () => {
hoverTimeout = setTimeout(() => {
description.classList.add('hoverDescription');
}, 3000); // Show after 3 seconds
});
item.addEventListener('mouseleave', () => {
clearTimeout(hoverTimeout); // Clear the timeout if mouse leaves
description.classList.remove('hoverDescription'); // Hide the description
});
</script>
我做了一个例子,根据您的解释,我相信您想要这样的东西,我们需要查看您的 HTML,以便根据您的设置进行精确定制。但您可以根据您的需要调整此功能。
仅当您将鼠标悬停在父级上一定时间时才显示隐藏元素,当您不再将鼠标悬停在其上时隐藏该元素:
let lastCard = null
let timer = null
document.addEventListener('mousemove', show)
function show(e) {
// Check if you are hovering an element on which you want to reveal something
const target = e.target.closest('.card')
// If a previus card was revealed or has a timmer on it, hide the lement and remove the timmer
if (lastCard && (lastCard != target)) {
if (timer) {
clearTimeout(timer)
}
lastCard.querySelector('span').classList.remove('showDesc')
}
// if you are not hovering on an element that you want to reveal someting, cancel prevous timmers and do nothing (return)
if (!target) {
lastCard = null
if (timer) {
clearTimeout(timer)
}
return
}
// If you are hovering (moving the mouse) on the same element do nothing because the timmer is already active and you just have towait
if (lastCard == target) {
return
}
// Save the current card so you can hide the description if the mouse moves to a different element
lastCard = target
// Get the elemnt that you want to reveal
const desc = target.querySelector('span')
// And in 3 sections (if the user keeps hovering the parent element) show it
timer = setTimeout(() => {
desc.classList.add('showDesc')
}, 3000)
}
.wrap {
display: flex;
gap: 1rem;
}
.card {
display: flex;
flex-direction: column;
align-items: center;
width: 150px;
height: 150px;
cursor: pointer;
border: 1px solid black;
border-radius: 6px;
padding: 6px;
text-align: center;
}
.card span {
display: none;
}
.card .showDesc {
display: block;
}
<div class="wrap">
<div class='card'>
<h3>
Title 1
</h3>
<span>This is a description</span>
</div>
<div class='card'>
<h3>
Title 2
</h3>
<span>This is yet another</span>
</div>
<div class='card'>
<h3>
Title 2
</h3>
<span>Believe it or not description</span>
</div>
</div>