JavaScript匀速运动停止条件与抖动修复
本文探讨JavaScript中匀速运动的停止逻辑。当固定速度与整数目标值不匹配时,元素会在目标点附近来回抖动。通过引入Math.abs判断距离并强制修正最终位置,可有效解决该问题,确保动画平滑停止。
匀速运动停止条件与抖动问题分析
首先回顾之前的匀速运动代码,在修改速度speed后,会出现怎样的bug。这里增加了两个标杆用于测试。
代码如下:
<style type="text/css">
#div1 {
width: 100px;
height: 100px;
position: absolute;
background: red;
top: 50px;
left: 600px;
}
#div2 {
width: 1px;
height: 300px;
position: absolute;
left: 300px;
top: 0;
background: black;
}
#div3 {
width: 1px;
height: 300px;
position: absolute;
left: 100px;
top: 0;
background: black;
}
</style>
<script type="text/javascript">
var time = null;
function startMove(iTarget) {
var oDiv = document.getElementById("div1");
clearInterval(time);
time = setInterval(function() {
var speed = 0;
if (oDiv.offsetLeft < iTarget) {
speed = 7;
} else {
speed = -7;
}
// 其实这种情况是有问题的
oDiv.style.left = oDiv.offsetLeft + speed + 'px';
}, 30)
}
</script>
</head>
<body>
<input type="button" id="btn" value="到100" onclick="startMove(100)" />
<input type="button" id="btn" value="到300" onclick="startMove(300)" />
<div id="div1">
</div>
<div id="div2">
</div>
<div id="div3">
</div>
</body>
抖动产生的原因
如果将速度设置为7这样的奇数,而目标点是整数,就会出现无法到达目标点或在目标点附近来回抖动的bug。

为什么会出现这种情况呢?
实际上,当物体到达目标点时,无法精确停在目标点上。例如目标点是100,每次移动7个单位,此时它要么超过目标点,要么未到达。
这意味着永远无法精确到达目标点,这与之前的缓冲运动有些类似。
修正后的停止逻辑
那么到底如何计算才算到达了目标点呢?
举个例子:你打车去某个地方,司机通常会在距离目的地10米或20米的地方停下来,这就视为到达。不可能要求汽车紧贴着目标点停下。
因此,程序也是一样的,只要物体与目标点之间的距离近到一定程度,就不再继续移动,即可认为已到达。
我们看下修改后的代码:
代码如下:
<script type="text/javascript">
var time = null;
function startMove(iTarget) {
var oDiv = document.getElementById("div1");
clearInterval(time);
time = setInterval(function() {
var speed = 0;
if (oDiv.offsetLeft < iTarget) {
speed = 7;
} else {
speed = -7;
}
if (Math.abs(iTarget - oDiv.offsetLeft) <= 7) {
clearInterval(time);
oDiv.style.left=iTarget+'px';
} else {
oDiv.style.left = oDiv.offsetLeft + speed + 'px';
}
}, 30)
}
</script>
代码实现与解释
解释一下:这里为什么要用 Math.abs 取绝对值呢?
理由很简单,因为速度可能是正的也可能是负的。
现在我们设定,只要目标和物体之间的距离小于等于7,就算到达。为什么是7呢?因为下一次运动的步长都不足7个单位了。此时我们可以认为它到达了目标点。
那现在问题又来了,这样写并没有精确地停在目标点的位置。所以我们加了一句简单的话,直接让left等于目标点:oDiv.style.left=iTarget+'px';
实际上最后一次走的不足7个单位,但是程序运行速度极快,人眼是看不出来的。
这个时候就没有问题了。
这个就是匀速运动的停止条件。有朋友问,为什么缓冲运动没有这么麻烦呢?
因为它的速度是变化的,越来越小,直到最后甚至只移动1个单位,一步一步前进肯定不会出现这样的问题。
JavaScript将图片转换为Base64编码的两种途径
2026-11-05 16:43:05
怎么在 Vue 或 React 项目中正确集成 animate.js
2026-11-05 10:23:38
JS注册事件:addEventListener基础语法与参数详解
2026-11-05 08:44:56
JSP和JS的区别:运行环境与服务端/客户端职责解析
2026-11-04 23:34:36
pdf.js 官方下载地址:GitHub Release 获取预编译包
2026-11-04 23:07:27
