当我将鼠标悬停在 div 上时动画应该开始

Animation should start when I hover over the div

我想执行以下操作:只有当我将鼠标悬停在 div 上时,动画才会开始。在我将鼠标悬停在 div 上之后,结束数字应该保持可见并且不会更改为起始值。

这是我的代码:

<!DOCTYPE html>
<html lang="en">
<head>
<title>Animation</title>
<style>
    .counter{
        color: white;
        font-size: 100px;
        height: 300px;
        width: 400px;
        background-color: black;
        display: flex;
        align-items:center;
        justify-content: center;
    }

    .animate{
        position:absolute;
        opacity:0;
        transition:0s 180s;
    }
    .animate:hover {
        opacity:1;
        transition:0s;
    }

   
</style>
</head>

<body>
    
    <div id="animate" style="background-color: orange; width: 300px; height: 200px;" class="counter" data-target="500">0</div>

<script>
const counters = document.querySelectorAll('.counter');
for(let n of counters) {
  const updateCount = () => {
    const target = + n.getAttribute('data-target');
    const count = + n.innerText;
    const speed = 5000; // change animation speed here
    const inc = target / speed; 
    if(count < target) {
      n.innerText = Math.ceil(count + inc);
      setTimeout(updateCount, 1);
    } else {
      n.innerText = target;
    }
  }
  updateCount();
}
</script>

</body>
</html>

将 onmousover 添加到 id="animate"

<div id="animate" style="background-color: orange; width: 300px; height: 200px;" class="counter" data-target="500" onmouseover="animationEffect();">0</div>

将整个脚本包装在一个方法中:

function animationEffect(){
    const counters = document.querySelectorAll('.counter');
    for(let n of counters) {
    const updateCount = () => {
        const target = + n.getAttribute('data-target');
        const count = + n.innerText;
        const speed = 5000; // change animation speed here
        const inc = target / speed; 
        if(count < target) {
        n.innerText = Math.ceil(count + inc);
        setTimeout(updateCount, 1);
        } else {
        n.innerText = target;
        }
    }
    updateCount();
    }
}

应该可以解决问题

编辑:

旧答案指的是编辑前的问题。对于当前情况,可以执行以下操作:

const updateCount = n => {
  const target = +n.getAttribute('data-target')
  const count = +n.innerText
  const speed = 5000 // change animation speed here
  const inc = target / speed
  if (count < target) {
    n.innerText = Math.ceil(count + inc)
    requestAnimationFrame(() => updateCount(n))
  } else {
    n.innerText = target
  }
}

const counters = document.querySelectorAll('.counter')
for (let n of counters) {
  n.addEventListener('mouseenter', () => updateCount(n), {
    once: true
  })
}
.counter {
  color: white;
  font-size: 100px;
  height: 300px;
  width: 400px;
  background-color: black;
  display: flex;
  align-items: center;
  justify-content: center;
}

.animate {
  position: absolute;
  opacity: 0;
  transition: 0s 180s;
}

.animate:hover {
  opacity: 1;
  transition: 0s;
}
<div id="animate" style="background-color: orange; width: 300px; height: 200px" class="counter" data-target="500">
  0
</div>

旧答案:

您需要添加一个 mouseenter event to the parent element. Note that the {once: true} 选项,以使事件只触发一次。

const parent = document.getElementById('parent')
parent.addEventListener('mouseenter', mouseEnterHandler, {once: true})

然后定义mouseEnterHandler回调如下:

function mouseEnterHandler() {

  for (let n of counters) {
    n.style.display = 'block'
    updateCount(n)
  }

  /* If you only have one counter then just get it by its Id:
   const div = document.getElementById('hover-content')
   div.style.display = 'block'
   updateCount(div)
  */
}

n.style.display = 'block' 将使计数器可见,因此不需要 css 规则 #parent:hover #hover-content { display:block; }.

这是一个工作示例:

const updateCount = n => {
  const target = +n.getAttribute('data-target')
  const count = +n.innerText
  const speed = 5000 // change animation speed here
  const inc = target / speed
  if (count < target) {
    n.innerText = Math.ceil(count + inc)
    requestAnimationFrame(() => updateCount(n))
  } else {
    n.innerText = target
  }
}

const counters = document.querySelectorAll('.counter')
const parent = document.getElementById('parent')
parent.addEventListener('mouseenter', mouseEnterHandler, {
  once: true
})

function mouseEnterHandler() {
  for (let n of counters) {
    n.style.display = 'block'
    updateCount(n)
  }
}
.counter {
  color: white;
  font-size: 100px;
  height: 140px;
  width: 400px;
  background-color: black;
  display: flex;
  align-items: center;
  justify-content: center;
}

#hover-content {
  display: none;
}
<div id="parent">
  Some content
  <div hidden id="hover-content" class="counter" data-target="232">0</div>
</div>