JavaScript 多物体运动实现:解决定时器冲突问题

作者:竹影

时间:2026-10-28

浏览:567

本文分析JavaScript中多物体动画常见的定时器冲突Bug。当多个元素共用一个全局timer变量时,后触发的运动会覆盖前一个运动。通过为每个DOM对象绑定独立的timer属性,实现各物体运动互不干扰,从而正确支持多物体同时运动。

文章目录

多物体运动与定时器冲突分析

回顾之前的运动代码,我们需要验证其是否支持多物体同时运动,并分析可能产生的问题。

相关代码实现如下:

<style type="text/css">
div {
width: 100px;
height: 50px;
background: red;
margin: 10px;
            }
}</style>

HTML结构代码如下:

<body>
<div></div>
<div></div>
<div></div>
</body>

对应的JavaScript逻辑代码如下:

代码如下:

<script type="text/javascript">
window.onload = function() {
var aDiv = document.getElementsByTagName('div');
for (var i = 0; i < aDiv.length; i++) {
aDiv[i].onmouseover = function() {
startMove(this, 400);
                    };
aDiv[i].onmouseout = function() {
startMove(this, 100);
                    };
                }
            }
var timer = null;
function startMove(obj, iTarget) {
clearInterval(timer);
timer = setInterval(function() {
var speed = (iTarget - obj.offsetWidth) / 6;
speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);
if (obj.offsetWidth == iTarget) {
clearInterval(timer);
} else {
obj.style.width = obj.offsetWidth + speed + 'px';
                    }
}, 30);
            }
</script>

当鼠标移入第一个div时,动画运行正常。然而,如果此时鼠标移入第二个或第三个div,就会出现Bug。

造成这一现象的原因是什么?从运行结果可以看出,动画并未正常完成。

实际上,整个程序中只存在一个全局定时器。例如,当第一个div开始运动后,如果鼠标移入第二个div,前一个div的定时器就会被清除,导致其动画卡在当前位置。

因此,核心问题在于整个程序只共享了一个定时器变量。如何解决这个问题呢?

解决方案:独立定时器属性

解决方案如下:

方法很简单,将定时器作为每个运动物体的属性进行存储。这样,每个物体都拥有自己的定时器,关闭或开启时操作的都是对应物体上的定时器。

通过这种方式,各个物体的运动就可以完全互不干扰地运行。

修改后的JavaScript代码如下:

代码如下:

<script type="text/javascript">
window.onload = function() {
var aDiv = document.getElementsByTagName('div');
for (var i = 0; i < aDiv.length; i++) {
aDiv[i].timer=null; // 把定时器作为一个物体的属性存起来
aDiv[i].onmouseover = function() {
startMove(this, 400);
                    };
aDiv[i].onmouseout = function() {
startMove(this, 100);
                    };
                }
            }
function startMove(obj, iTarget) {
clearInterval(obj.timer);
obj.timer = setInterval(function() {
var speed = (iTarget - obj.offsetWidth) / 6;
speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);
if (obj.offsetWidth == iTarget) {
clearInterval(obj.timer);
} else {
obj.style.width = obj.offsetWidth + speed + 'px';
                    }
}, 30);
            }
</script>

经过上述修改,程序已无问题,能够正确支持多物体的运动。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章