快速点击jQuery轮播切换按钮时remove()函数不生效是什么原因,如何解决?
问题本质
这是前端交互动画场景下非常常见的竞态条件问题,并不是remove()方法本身失效:
- 你当前的轮播切换动画耗时700ms,快速多次点击按钮时,上一次切换的动画还没执行完毕,新的点击逻辑就已经触发,会重复克隆ul元素、堆积动画队列
- 等第一次动画结束执行
$('#slider ul').first().remove()时,你原本要删除的旧ul已经不是DOM里的第一个ul元素了,要么删错了正在使用的元素,要么多份ul共存导致计数、位置完全混乱,最终表现为轮播异常。
解决方案
最直接可靠的方式是新增动画执行锁,保证上一次切换动画完全结束前,点击不会触发新的逻辑,修改代码如下:
$(window).on('load', function() { 'use strict'; const imageCount = $("#slider ul li").length; const imageWidth = $("#slider ul li img").first().width(); const totalWidth = (imageWidth * imageCount) + 'px'; let leftPosition = 0; let counter = 0; // 新增动画锁,标记当前是否有切换动画正在执行 let isAnimating = false; $('#slider ul').css('width', totalWidth); $('#next').click(function(){ // 动画执行中直接忽略本次点击 if(isAnimating) return; // 上锁,阻止后续点击触发 isAnimating = true; counter++; if(counter === imageCount){ $('#slider ul').clone().appendTo('#slider'); $('#slider ul').last().css('left', imageWidth + 'px'); leftPosition = `-${totalWidth}` $('#slider ul').last().animate({left: 0}, 700, 'easeInQuad'); $('#slider ul').first().animate({left: leftPosition}, 700, 'easeInQuad', function(){ $('#slider ul').first().remove(); // 动画执行完毕,解锁 isAnimating = false; }); counter = 0; } else{ leftPosition = `-${counter * imageWidth}px` $('#slider ul').animate( {left : leftPosition}, 700, 'easeInQuad', function(){ // 动画执行完毕,解锁 isAnimating = false; }); } }); $('#previous').click(function(){ // 动画执行中直接忽略本次点击 if(isAnimating) return; // 上锁,阻止后续点击触发 isAnimating = true; counter--; if(counter < 0){ counter = imageCount-1; $('#slider ul').clone().appendTo('#slider'); $('#slider ul').last().css('left', `-${totalWidth}`); leftPosition = `-${counter * imageWidth}`; $('#slider ul').last().animate({left: leftPosition}, 700, 'easeInQuad'); $('#slider ul').first().animate({left: imageWidth + 'px'}, 700, 'easeInQuad', function(){ $('#slider ul').first().remove(); // 动画执行完毕,解锁 isAnimating = false; }); } else { leftPosition = `-${counter * imageWidth}px`; $('#slider ul').animate( {left : leftPosition}, 700, 'easeInQuad', function(){ // 动画执行完毕,解锁 isAnimating = false; }); } }); });
如果需要进一步优化体验,还可以额外加上按钮点击防抖、动画队列清空的逻辑,上述锁方案已经可以解决绝大多数快速点击导致的异常问题。
内容的提问来源于stack exchange,提问作者Yongstephi
相关产品推荐
相关产品推荐

