
本文旨在解决在使用 Counter-Up 2 插件时,当页面上下滚动导致计数器元素重新进入视口时,计数器停止在随机数的问题。通过使用 Intersection Observer API 结合 Counter-Up 2 的方法,确保计数器每次进入视口都能从初始值计数到目标值,避免重复滚动导致的计数异常。
在使用 Counter-Up 插件实现数字滚动效果时,一个常见的问题是,当用户滚动页面,使得计数器元素离开视口后再重新进入视口时,计数器可能会停止在随机数,而不是从初始值重新开始计数。 这通常是因为 Counter-Up 默认的行为是在页面加载时执行一次计数动画,之后不再重新触发。
为了解决这个问题,我们可以使用 Intersection Observer API 来监听计数器元素是否进入视口。当元素进入视口时,我们才启动计数器。同时,我们需要记录元素是否已经计数过,防止重复计数。
以下是具体的实现步骤:
1. 引入 Counter-Up 2 插件
首先,确保你已经引入了 Counter-Up 2 插件。Counter-Up 2 提供了更灵活的配置和更好的性能。
2. HTML 结构
你的 HTML 结构应该包含带有 counter 类名的元素,这些元素将用于显示计数器。
10
Years of
Experience
+
5000
Products
Sold
3. 使用 Intersection Observer API 和 Counter-Up 2
以下 JavaScript 代码使用 Intersection Observer API 监听 counter 元素,并在元素进入视口时启动计数器。同时,使用 is-visible 类来标记元素是否已经计数过,以避免重复计数。
const counterUp = window.counterUp.default
const callback = entries => {
entries.forEach(entry => {
const el = entry.target
if (entry.isIntersecting && !el.classList.contains('is-visible')) {
counterUp(el, {
duration: 500,
delay: 10,
})
el.classList.add('is-visible')
} else {
el.classList.remove('is-visible')
}
})
}
const IO = new IntersectionObserver(callback, {
threshold: 1
})
const els = document.querySelectorAll('.counter')
els.forEach((el) => {IO.observe(el)})代码解释:
- counterUp: 从 window.counterUp.default 获取 Counter-Up 2 的默认导出函数。
- callback: Intersection Observer 的回调函数。它接收一个 entries 数组,每个 entry 代表一个被观察的元素的状态。
- entry.isIntersecting: 判断元素是否进入视口。
- !el.classList.contains('is-visible'): 判断元素是否已经计数过。
- counterUp(el, { duration: 500, delay: 10 }): 启动计数器,duration 设置动画持续时间,delay 设置每次计数之间的延迟。
- el.classList.add('is-visible'): 标记元素已经计数过。
- el.classList.remove('is-visible'): 当元素离开视口时,移除 is-visible 类,以便下次进入视口时可以重新计数。
- IntersectionObserver: 创建一个 Intersection Observer 实例,用于监听元素是否进入视口。threshold: 1 表示元素完全进入视口时触发回调函数。
- document.querySelectorAll('.counter'): 获取所有带有 counter 类名的元素。
- IO.observe(el): 开始观察每个元素。
4. CSS (可选)
以下 CSS 代码仅用于示例,可以根据你的实际需求进行修改。
.row{height:1000px;}总结:
通过使用 Intersection Observer API 结合 Counter-Up 2 插件,我们可以有效地解决计数器在重复滚动时停止在随机数的问题。 这种方法确保计数器每次进入视口都能从初始值计数到目标值,提供更流畅和可靠的用户体验。记住,threshold 参数可以根据实际需求进行调整,以控制何时触发计数器。 此外,如果你的页面有大量的计数器元素,可以考虑优化 Intersection Observer 的配置,例如使用 rootMargin 来提前加载计数器,以提升性能。










