使用JavaScript实现多雨滴下落效果遇问题:代码仅执行一次求排查
多雨滴下落效果的问题排查与修复
原代码的核心问题
- 全局共享状态导致同步运动:所有雨滴共用同一个
yPosition变量,会让所有雨滴同步移动,无法实现独立下落的效果;重置位置时还错误地操作了整个DOM集合的样式。 - 定时器滥用导致逻辑混乱:在
Raining函数内部重复调用setInterval(Raining, 40),每次触发都会生成新的定时器,短时间内会堆积大量重复定时器,不仅性能爆炸,还会让运动逻辑彻底混乱。 - DOM元素操作错误:
rain = document.querySelectorAll('div')会选中页面初始的.rain元素,而且Raining里直接操作rain.style.top——但rain是DOM元素集合,不是单个元素,这会直接报错。 - 重复触发初始化逻辑:循环给每个雨滴调用
Raining(),进一步加剧了定时器泛滥的问题。
修复后的完整代码
HTML
<div class="rain"></div>
CSS
* { margin: 0; padding: 0; box-sizing: border-box; } body { overflow: hidden; height: 100vh; background-color: #1a1a2e; /* 加深色背景让雨滴更明显 */ } .rain-drop { position: absolute; top: 0; background-color: royalblue; width: 3px; height: 20px; }
JavaScript
// 可调整的参数 const RAIN_COUNT = 20; const MAX_FALL_SPEED = 3; const MIN_FALL_SPEED = 1; // 创建雨滴元素并初始化独立状态 function createRaindrops() { const body = document.querySelector('body'); for (let i = 0; i < RAIN_COUNT; i++) { const drop = document.createElement('div'); drop.classList.add('rain-drop'); // 随机水平位置(百分比) const randomX = Math.random() * 100; drop.style.left = `${randomX}%`; // 随机初始垂直位置(让雨滴一开始分布在不同高度) const randomY = -Math.random() * window.innerHeight; drop.dataset.y = randomY; // 随机下落速度 const randomSpeed = Math.random() * (MAX_FALL_SPEED - MIN_FALL_SPEED) + MIN_FALL_SPEED; drop.dataset.speed = randomSpeed; body.appendChild(drop); } } // 统一更新所有雨滴的位置 function updateRaindrops() { const raindrops = document.querySelectorAll('.rain-drop'); const windowHeight = window.innerHeight; raindrops.forEach(drop => { let currentY = parseFloat(drop.dataset.y); const speed = parseFloat(drop.dataset.speed); currentY += speed; // 雨滴超出屏幕底部后,重置到顶部随机位置 if (currentY > windowHeight) { currentY = -20; // 让雨滴完全从顶部进入视野 drop.style.left = `${Math.random() * 100}%`; // 重置水平位置,模拟真实降雨的随机性 } drop.dataset.y = currentY; drop.style.top = `${currentY}px`; }); } // 启动降雨动画 createRaindrops(); setInterval(updateRaindrops, 40);
修复说明
- 独立状态管理:每个雨滴通过
dataset存储自己的垂直位置和下落速度,实现完全独立的运动轨迹。 - 单一定时器驱动:只创建一个全局定时器,统一更新所有雨滴的位置,彻底避免定时器泛滥的问题。
- 更自然的降雨效果:初始化时随机设置雨滴的初始高度和下落速度,重置时也随机水平位置,模拟真实降雨的无序感。
- 精准DOM操作:用
.rain-drop类名标记雨滴元素,避免误选页面其他div,确保样式操作只作用在目标元素上。
内容的提问来源于stack exchange,提问作者Wojtek1911
相关产品推荐
相关产品推荐

