关于JavaScript计时器动画问题

各位大佬,请问JavaScript做前端动画的时候,如果设置成这样子,动画函数中的if语句不是>=而是==,结果会是盒子只在所定义的距离参数target=200时才会停下,不然会一直动下去,这是为什么呢?求解答

<body>
    <div>this is a cartoon</div>
    <p>flash</p>
    <button>点击</button>
    <script>
        function aminate(obj, target) {
            clearInterval(obj.time);
            obj.time = setInterval(function () {
                if (obj.offsetLeft == target) {
                    clearInterval(obj.time);
                }
                obj.style.left = obj.offsetLeft + 1 + 'px';
            }, 30)
        }
        var div = document.querySelector('div');
        var span = document.querySelector('p');
        var btn = document.querySelector('button');
        aminate(div, 300);
        btn.addEventListener('click', function () {
            aminate(span, 300);
        });
    </script>
</body>

第二个小问题,这是一个点击+盒子移动动画的程序,第一次点击移动到指定位置,到之后点击还可以移动一小段距离,请问这是为什么呢?

<body>
    <div>this is a cartoon</div>
    <p>flash</p>
    <button>点击</button>
    <script>
        function aminate(obj, target) {
            clearInterval(obj.time);
            obj.time = setInterval(function () {
                if (obj.offsetLeft >= target) {
                    clearInterval(obj.time);
                }
                obj.style.left = obj.offsetLeft + 1 + 'px';
            }, 30)
        }
        var div = document.querySelector('div');
        var span = document.querySelector('p');
        var btn = document.querySelector('button');
        aminate(div, 300);
        btn.addEventListener('click', function () {
            aminate(span, 300);
        });
    </script>
</body>

 

1.

你是每次重新读取offsetLeft也就是相对距离来进行递增,读取到的值并不是每次都+1的,你可以通过打印出每次setInterval拿到的offsetLeft发现这个问题。可以通过第一次读取,之后维护使用这个值来解决,如下

        function aminate(obj, target) {
            clearInterval(obj.time);
			let left = obj.offsetLeft;
            obj.time = setInterval(function () {
				left++;
                if (left == target) {
                    clearInterval(obj.time);
                }
                obj.style.left = left  + 'px';
				
				console.log(obj.style.left)
            }, 30)
        }

 

2.

你每次点击按钮时都会触发animate,同时也会创建一个setInterval,即使你进去就清除了它,他也会执行一次,如果要避免,在if条件内加个return让后续不再执行,或者加个else

         function aminate(obj, target) {
            clearInterval(obj.time);
			let left = obj.offsetLeft;
            obj.time = setInterval(function () {
				left++;
                if (obj.offsetLeft >= target) {
                    clearInterval(obj.time);
					return;
                }
                obj.style.left = obj.offsetLeft+1  + 'px';
				
				console.log(obj.style.left)
            }, 30)
        }

 

如有帮助 请采纳 谢谢

大佬可以我又有一点问题。按照你的指导我修改了代码,并且加了一点点小功能,但代码又不如人意

我本来想做轮播图,通过这个做动画,但轮播图没有按照想的进行运动

function aminate(obj, target, callback) {
    clearInterval(obj.time);
    let w=obj.offsetLeft;
    obj.time = setInterval(function () {
        var step = ((target - w) / 10);
        step = step > 0 ? Math.ceil(step) : Math.floor(step);
        if (w == target) {
            clearInterval(obj.time);
            if (callback) {
                callback();
            }
            return;
        }
        obj.style.left = w + step + 'px';
    }, 35)
}