如何实现网页仅向下滚动触发元素动画 修复JS上下滚动都触发的问题
问题根因
你当前的代码没有判断滚动方向,同时元素离开视口就会移除visible类,导致向上滚动时元素重新进入视口也会再次添加类触发动画。
改造后完整代码
var scroll = window.requestAnimationFrame || function(callback){ window.setTimeout(callback,1000/60) }; // 存储上一次滚动的纵坐标位置,初始值为0 let lastScrollY = 0; var elements = document.querySelectorAll(".question-box"); function loop(){ // 获取当前滚动位置 const currentScrollY = window.pageYOffset || document.documentElement.scrollTop; // 仅向下滚动时执行元素类名操作 if (currentScrollY > lastScrollY) { elements.forEach(element => { // 如果元素已在视口内且还没加visible类,才添加类触发动画 if (isElementInViewport(element) && !element.classList.contains("visible")){ element.classList.add("visible"); } }); } // 如果你需要向上滚动时隐藏元素、下次向下滚再重新触发动画,可以放开下面这段注释 // else { // elements.forEach(element => { // if (!isElementInViewport(element)){ // element.classList.remove("visible"); // } // }) // } // 更新上一次滚动位置 lastScrollY = currentScrollY; scroll(loop); } loop(); // 原有的视口判断工具函数 function isElementInViewport(el) { if (typeof jQuery === "function" && el instanceof jQuery) { el = el[0]; } var rect = el.getBoundingClientRect(); return ( (rect.top <= 0 && rect.bottom >= 0) || (rect.bottom >= (window.innerHeight || document.documentElement.clientHeight) && rect.top <= (window.innerHeight || document.documentElement.clientHeight)) || (rect.top >= 0 && rect.bottom <= (window.innerHeight || document.documentElement.clientHeight)) ); }
核心改动说明
- 新增
lastScrollY变量记录上一次滚动的位置,每次执行loop时和当前滚动位置对比,只有当前滚动位置大于上次位置(即向下滚动)时才执行类添加操作 - 加类时增加了
!element.classList.contains("visible")的判断,避免重复给已触发动画的元素加类 - 默认注释了移除类的逻辑,保证元素动画触发后保持可见状态,如果需要每次向下滚动进入视口都重新触发动画,放开移除类的注释即可
内容的提问来源于stack exchange,提问作者Ajil P
相关产品推荐
相关产品推荐

