如何实现网页淡入淡出动画生效一次后禁用?
实现淡入动画首次触发后禁用的纯JS方案
要让淡入淡出动画仅在首次触发后就不再执行,核心是避免已完成动画的元素被重复处理,或者在所有元素都完成动画后彻底移除滚动监听,下面是两种实用的修改方案:
方案1:标记已动画元素,跳过重复处理
给每个.fade元素添加自定义属性标记是否完成动画,后续滚动时直接跳过这些元素,同时不再移除visible类,确保元素保持显示状态:
window.addEventListener('scroll', fade); function fade() { // 只选择未标记为已动画的元素 let animations = document.querySelectorAll('.fade:not([data-animated="true"])'); if (animations.length === 0) { // 所有元素都完成动画后,移除滚动监听节省性能 window.removeEventListener('scroll', fade); return; } const windowHeight = window.innerHeight; for (let i = 0; i < animations.length; i++) { const top = animations[i].getBoundingClientRect().top; if (top < windowHeight) { animations[i].classList.add('visible'); // 标记该元素已完成动画 animations[i].setAttribute('data-animated', 'true'); } // 移除原有的else分支,不再移除visible类 } } // 页面加载时先执行一次,避免初始就在视口内的元素没触发动画 fade();
方案2:统计完成数量,全部完成后移除监听
如果不需要单个元素的标记,也可以统计已完成动画的元素数量,当数量等于总.fade元素数时,直接移除滚动事件监听:
const allFades = document.querySelectorAll('.fade'); let animatedCount = 0; window.addEventListener('scroll', fade); function fade() { const windowHeight = window.innerHeight; for (let i = 0; i < allFades.length; i++) { // 跳过已完成动画的元素 if (allFades[i].classList.contains('visible')) continue; const top = allFades[i].getBoundingClientRect().top; if (top < windowHeight) { allFades[i].classList.add('visible'); animatedCount++; } } // 所有元素都完成动画后,移除滚动监听 if (animatedCount === allFades.length) { window.removeEventListener('scroll', fade); } } // 初始执行一次,确保视口内元素正常触发动画 fade();
关键修改说明
- 移除原代码中
else分支,避免滚动时反复移除visible类导致动画重复触发; - 通过标记元素或统计完成数量,确保每个元素的动画仅执行一次;
- 所有元素完成动画后移除滚动监听,减少不必要的性能消耗。
内容的提问来源于stack exchange,提问作者engr. hasnat
相关产品推荐
相关产品推荐

