如何让jQuery的.hover()方法适配触控设备的手指滑动操作
适配触控滑动的实现方案
核心思路
你之前直接替换hover为ontouchmove失效的原因是触控事件的坐标参数和鼠标事件结构不同,原库读取不到正确的位置信息。本方案不需要修改原库的核心逻辑,只要把触控设备的触摸事件映射为原库依赖的标准鼠标事件即可,原库绑定的hover(本质是mouseenter+mouseleave)和mousemove事件都可以通过原生API模拟触发,完全适配原库的参数要求。
具体实现步骤
- 首先确定原库绑定事件的图片容器选择器,和你初始化该库时使用的容器选择器保持一致
- 给容器绑定触控事件,将触摸坐标映射为鼠标事件坐标后主动触发,代码示例如下:
// 替换为你实际使用的容器选择器 const $imgContainer = $('.swinger-container'); $imgContainer.on('touchstart touchmove touchend', function (e) { // 按需添加,避免触控时触发页面滚动等默认行为 e.preventDefault(); // 取第一个触摸点的坐标 const activeTouch = e.originalEvent.touches[0]; if (!activeTouch && e.type !== 'touchend') return; let triggerEvent; switch (e.type) { case 'touchstart': // 映射为鼠标进入容器事件,对应hover的触发起点 triggerEvent = new MouseEvent('mouseenter', { clientX: activeTouch.clientX, clientY: activeTouch.clientY, bubbles: true }); break; case 'touchmove': // 映射为鼠标移动事件,原库会根据这个坐标切换图片z-index triggerEvent = new MouseEvent('mousemove', { clientX: activeTouch.clientX, clientY: activeTouch.clientY, bubbles: true }); break; case 'touchend': // 映射为鼠标离开容器事件,对应hover的结束 triggerEvent = new MouseEvent('mouseleave', { bubbles: true }); break; } // 触发事件,原库会自动执行对应的切换逻辑 this.dispatchEvent(triggerEvent); });
常见问题调整
- 如果触控时点击其他功能异常,可删除
touchstart和touchend阶段的e.preventDefault(),仅保留touchmove阶段的阻止默认行为即可 - 如果原库的事件是绑定在
document而非容器本身,将最后一行的this.dispatchEvent改成document.dispatchEvent即可 - 如果滑动灵敏度不符合预期,可以给
touchmove事件加节流处理,降低触发频率避免卡顿:
// 节流函数,16ms触发一次对应60帧 function throttle(func, delay = 16) { let lastCall = 0; return function(...args) { const now = Date.now(); if (now - lastCall < delay) return; lastCall = now; return func.apply(this, args); } } // touchmove的处理逻辑包一层节流即可
内容的提问来源于stack exchange,提问作者François Lacruche
相关产品推荐
相关产品推荐

