求助:JQuery结合Hammer.js实现列表触摸滚动的问题
适配现有jQuery滚轮切换逻辑的Hammer.js触摸滚动实现
问题背景
已有一个可正常运行的jQuery函数scrollToNearest,通过鼠标滚轮的delta值判断方向,实现列表项的前后滚动切换。现在需要借助Hammer.js将该逻辑适配到触摸操作场景,但使用swipe和pan事件未成功。
原函数代码:
$.fn.scrollToNearest = function (delta) { var direction = delta > 0 ? "prev" : "next"; // 获取滚动方向 var elementToScroll = $(this)[direction](); // 获取需要滚动到视图内的元素 // 滚动元素到视图内 if (elementToScroll.length) { var id = elementToScroll.attr("id"); document.querySelector("#" + id).scrollIntoView({ behavior: "smooth", block: "end", }); } return this; // 支持方法链式调用 };
解决方案
1. 核心思路
利用Hammer.js监听垂直方向的触摸滑动事件(swipe或pan),根据滑动方向对应传入scrollToNearest所需的delta值:
- 向上滑动 → 传入正delta(对应切换到上一项)
- 向下滑动 → 传入负delta(对应切换到下一项)
同时需要准确识别当前处于可视区域的列表项,作为调用scrollToNearest的上下文。
2. 具体实现代码
初始化Hammer.js并监听Swipe事件
// 假设列表容器选择器为.list-container,列表项选择器为.list-item var listContainer = document.querySelector('.list-container'); var hammer = new Hammer(listContainer, { direction: Hammer.DIRECTION_VERTICAL // 仅监听垂直方向触摸操作 }); // 配置swipe识别灵敏度(阈值可根据需求调整) hammer.get('swipe').set({ threshold: 50 }); // 辅助函数:获取当前可视区域内的目标列表项(需根据实际列表结构调整) function getCurrentVisibleItem() { // 示例逻辑:取可视区域内的最后一个列表项作为当前项 return $('.list-item').filter(function() { var rect = this.getBoundingClientRect(); // 判断元素是否在可视区域内,可按需修改条件 return rect.top >= 0 && rect.bottom <= window.innerHeight; }).last(); } // 监听向上滑动(切换到上一项) hammer.on('swipeup', function() { var currentItem = getCurrentVisibleItem(); currentItem.scrollToNearest(1); }); // 监听向下滑动(切换到下一项) hammer.on('swipedown', function() { var currentItem = getCurrentVisibleItem(); currentItem.scrollToNearest(-1); });
可选:使用Pan事件实现(适合更灵敏的滑动判断)
如果swipe事件触发过于严格,可改用pan事件监听滑动结束时的位移方向:
hammer.get('pan').set({ direction: Hammer.DIRECTION_VERTICAL }); hammer.on('panend', function(e) { var currentItem = getCurrentVisibleItem(); // e.deltaY为负 → 向上滑动;为正 → 向下滑动 if (e.deltaY < 0) { currentItem.scrollToNearest(1); } else if (e.deltaY > 0) { currentItem.scrollToNearest(-1); } });
3. 关键注意事项
- 当前项识别逻辑:上述示例中的
getCurrentVisibleItem是基础实现,你可以根据列表实际结构优化,比如通过active类标记当前选中项,直接用$('.list-item.active')获取,更准确高效。 - 列表结构要求:原函数使用
prev()和next()方法,要求所有列表项是同级DOM元素,需确保结构符合预期。 - Hammer.js配置:务必设置
direction: Hammer.DIRECTION_VERTICAL,避免干扰水平方向的触摸操作。
内容的提问来源于stack exchange,提问作者Francesco Pauselli
相关产品推荐
相关产品推荐

