如何让fullpage.js在桌面端与移动端横屏模式下支持水平拖拽
fullpage.js 移动端拖拽核心机制
- 移动端拖拽效果和
scrollOverflow配置无关,该配置仅用于处理单个section内部内容超出容器时的局部滚动,不控制整页拖拽切换逻辑。 - 移动端默认支持拖拽,是因为fullpage源码默认会给触摸设备绑定
touchstart/touchmove/touchend三个原生事件:touchstart阶段记录手指初始落点坐标,关闭容器过渡动画准备实时跟手touchmove阶段计算手指滑动偏移量,通过transform: translate3d()实时修改整页容器位移,实现跟手效果touchend阶段计算滑动距离、滑动速度,超过预设阈值就调用内置方法切换上/下section,未达阈值就回弹到当前section,切换/回弹过程通过CSStransition实现平滑动画
- 桌面端默认不支持拖拽,是因为源码内做了设备类型判断,非触摸设备仅绑定鼠标滚轮
wheel事件,不会绑定拖拽相关的事件逻辑,这也是手动给桌面端开scrollOverflow没有效果的根本原因。 - 移动端横屏拖拽失效,是因为fullpage内置的设备检测逻辑会将部分横屏状态误判为非触摸设备,跳过了触摸事件绑定,和配置项无关。
无依赖原生适配方案
第一步:调整初始化配置
去掉按设备类型切换scrollOverflow的判断,全局开启该配置,统一各端逻辑:
const options = { scrollOverflow: true, touchSensitivity: 5, // 拖拽触发阈值,数值越小越灵敏 normalScrollElementTouchThreshold: 3 // 避免内部滚动容器和整页拖拽冲突 }
初始化完成后直接调用内置API绑定桌面端鼠标拖拽逻辑即可,不需要修改fullpage源码。
第二步:绑定桌面端鼠标拖拽事件
逻辑完全对齐fullpage内置的移动端触摸事件逻辑,保证效果一致:
let isDragging = false; let startY = 0; let moveOffset = 0; const fpContainer = document.querySelector('#fullpage'); // 替换为你的fullpage根容器选择器 // 鼠标按下,对应移动端touchstart fpContainer.addEventListener('mousedown', (e) => { // 排除内部可滚动区域、交互元素上的操作,避免冲突 if (e.target.closest('.fp-scrollable') || e.target.closest('a,button,input,textarea')) return; isDragging = true; startY = e.clientY; fpContainer.style.transition = 'none'; }) // 鼠标移动,对应移动端touchmove document.addEventListener('mousemove', (e) => { if (!isDragging) return; moveOffset = e.clientY - startY; // 计算当前页基础偏移量,实现拖拽跟手效果 const activeSection = document.querySelector('.fp-section.active'); const activeIndex = Array.from(activeSection.parentNode.children).indexOf(activeSection); const baseOffset = activeIndex * window.innerHeight; fpContainer.style.transform = `translate3d(0, ${-baseOffset + moveOffset}px, 0)`; }) // 鼠标松开,对应移动端touchend document.addEventListener('mouseup', () => { if (!isDragging) return; isDragging = false; fpContainer.style.transition = ''; // 恢复过渡动画 const triggerThreshold = 50; // 拖拽超过50px触发翻页,可自行调整 if (Math.abs(moveOffset) > triggerThreshold) { moveOffset > 0 ? fullpage_api.moveSectionUp() : fullpage_api.moveSectionDown(); } else { // 拖拽距离不足,回弹到当前页 const activeSection = document.querySelector('.fp-section.active'); const activeIndex = Array.from(activeSection.parentNode.children).indexOf(activeSection); fpContainer.style.transform = `translate3d(0, ${-activeIndex * window.innerHeight}px, 0)`; } // 重置状态 startY = 0; moveOffset = 0; })
第三步:修复移动端横屏拖拽失效
去掉代码中所有deviceType == 'mobile'类的设备判断分支,不要针对特定设备屏蔽事件绑定,上述逻辑和fullpage内置的触摸事件逻辑互不冲突,横屏状态下触摸事件会正常触发,拖拽效果和竖屏完全一致。
注意:所有翻页操作直接调用fullpage内置的
moveSectionUp/moveSectionDown方法即可,动画时长、缓动函数和原生移动端拖拽完全一致,不会出现样式错位、动画不统一的问题。如果你的自定义容器有独立滚动条,只要给元素加上fp-scrollable类名,就会自动被事件拦截逻辑识别,不会和整页拖拽冲突。
内容的提问来源于stack exchange,提问作者HNG
相关产品推荐
相关产品推荐

