鼠标输入等待3秒后显示对话框/工具提示

问题描述 投票:0回答:3

我有一个元素,当鼠标悬停时,我会显示附加信息

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 来做到这一点?

javascript css events
3个回答
1
投票

我会建议一个CSS解决方案,因为:JavaScript不是必需的。

要在悬停时显示工具提示,只需使用

:hover
。对于出现的延迟,您可以使用 CSS 的
delay
animation

此外,通过使用 CSS 属性,您可以在工具提示的样式属性中为每个工具提示分配所需的
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>


0
投票

请将此脚本标签插入您的 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>

0
投票

我做了一个例子,根据您的解释,我相信您想要这样的东西,我们需要查看您的 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>

© www.soinside.com 2019 - 2024. All rights reserved.