iOS Safari下touchswipe触发jQuery .animate动画不生效如何解决?
核心原因
- 动画操作对象与属性错误:你当前使用animate修改外层
#sportCourtsRow的marginLeft,该元素是position: fixed、宽度100vw的固定定位容器,修改它的外边距只会移动整个容器本身,而非你想要的内部内容滚动偏移。如果你要移动的是ul内部的div元素,没有选中对应的内部元素,动画自然不会出现预期效果。 - iOS Safari兼容性问题:带有
-webkit-overflow-scrolling: touch属性的滚动容器,使用jQuery animate操作滚动属性时容易触发硬件加速渲染冲突,导致动画不生效。 - HTML结构不规范:ul的直接子元素应为li,直接在ul内嵌套div会导致浏览器布局计算异常,也可能影响动画效果。
解决方案
方案1:修正滚动动画逻辑(推荐,适配移动端滚动需求)
如果需求是横向滚动容器内的内容,直接操作容器的scrollLeft属性即可,同时添加硬件加速触发样式避免iOS兼容问题:
- 给
#sportCourtsRow添加CSS属性触发硬件加速:
#sportCourtsRow { transform: translateZ(0); -webkit-transform: translateZ(0); }
- 修改JS动画代码:
var swipebar = document.getElementById("sportCourtsRow"); let isAnimating = false; // 加动画锁避免重复触发 $(swipebar).swipe({ swipe: function(event, direction, distance, duration, fingerCount, fingerData) { if (distance > 80 && !isAnimating) { isAnimating = true; document.getElementById("monthTxt").innerHTML = "worked"; // 根据滑动方向调整滚动偏移,右滑减左滑加可自行调整 let offset = direction === 'left' ? 500 : -500; $("#sportCourtsRow").animate({ scrollLeft: `+=${offset}px` }, "slow", () => { isAnimating = false; }) } }, threshold: 0 });
方案2:使用原生API替代jQuery animate(兼容性更好)
如果修改后jQuery animate依然失效,可以直接用原生平滑滚动API,移动端适配性更高:
var swipebar = document.getElementById("sportCourtsRow"); let isAnimating = false; $(swipebar).swipe({ swipe: function(event, direction, distance, duration, fingerCount, fingerData) { if (distance > 80 && !isAnimating) { isAnimating = true; document.getElementById("monthTxt").innerHTML = "worked"; let offset = direction === 'left' ? 500 : -500; swipebar.scrollTo({ left: swipebar.scrollLeft + offset, behavior: 'smooth' }); // 600ms对应slow动画时长,解锁 setTimeout(() => { isAnimating = false; }, 600); } }, threshold: 0 });
方案3:如果确实要移动内部div的位置
给ul内部的div添加类名inner-swipe-container,使用CSS transition实现动画,比jQuery animate更稳定:
- 添加CSS:
.inner-swipe-container { transition: margin-left 0.6s ease; transform: translateZ(0); -webkit-transform: translateZ(0); }
- 修改JS代码:
var swipebar = document.getElementById("sportCourtsRow"); let isAnimating = false; $(swipebar).swipe({ swipe: function(event, direction, distance, duration, fingerCount, fingerData) { if (distance > 80 && !isAnimating) { isAnimating = true; document.getElementById("monthTxt").innerHTML = "worked"; document.querySelector(".inner-swipe-container").style.marginLeft = "500px"; setTimeout(() => { isAnimating = false; }, 600); } }, threshold: 0 });
最后建议修正HTML结构,将ul替换为div作为外层容器,避免列表元素的默认样式和结构规则带来的额外问题。
内容的提问来源于stack exchange,提问作者Torpid
相关产品推荐
相关产品推荐

