在移动端开发中,长按事件是常见的一种交互方式,可以实现长按操作触发特定的功能,例如复制、粘贴、删除等。本文将从多个方面对移动端长按事件进行详细阐述。
一、移动端长按事件与松开
长按事件分为两个部分,一个是按下的瞬间触发的事件,另一个是长按一定时间之后触发的事件。一般情况下,长按一定时间之后会弹出一个选项框,其中包含了很多操作,例如复制、粘贴、删除等。
document.getElementById('btn').addEventListener('touchstart', function (e) { // 长按 this.timer = setTimeout(function () { console.log('长按事件触发了') }, 1000) }) document.getElementById('btn').addEventListener('touchend', function (e) { // 松开 clearTimeout(this.timer) })
上面的代码是一个简单的长按事件的示例,通过设置一个定时器,在长按一定时间后触发长按事件功能,并在松开时清除定时器。其中,timer 为一个全局变量,要在松开的时候清除,避免定时器依旧运行。
二、移动端事件有哪些
除了长按事件,移动端还有很多其他操作方式的事件。
1. 点击事件
单次点击触发的事件,用于实现类似于网页中的点击跳转等功能。
document.getElementById('btn').addEventListener('click', function(){ console.log('点击事件触发了') })
2. 双击事件
快速两次点击触发的事件,用于实现类似于网页中的放大、缩小等功能。
document.getElementById('btn').addEventListener('dblclick', function(){ console.log('双击事件触发了') })
3. 滑动事件
手指在屏幕上滑动时触发的事件,用于实现类似于轮播图、画廊等功能。
document.getElementById('btn').addEventListener('touchmove', function(){ console.log('滑动事件触发了') })
4. 手势事件
手指在屏幕上做出的各种手势,例如旋转、捏合、拖拽等。
document.getElementById('btn').addEventListener('gesturestart', function(){ console.log('手势开始事件触发了') }) document.getElementById('btn').addEventListener('gesturechange', function(){ console.log('手势变化事件触发了') }) document.getElementById('btn').addEventListener('gestureend', function(){ console.log('手势结束事件触发了') })
三、移动端长按事件弹出复制按钮插件
移动端长按事件弹出复制按钮插件是一个很常见的需求,可以通过自定义一个长按事件触发复制框,并将选中的文本复制到剪贴板中实现。下面是一个例子:
function longPress(element, copyBtn) { let initX let initY let timer = null const MIN_DISTANCE = 10 element.addEventListener('touchstart', (e) => { if (e.touches.length > 1) { return } initX = e.changedTouches[0].clientX initY = e.changedTouches[0].clientY timer = setTimeout(() => { copyBtn.show(element) }, 800) }) element.addEventListener('touchmove', (e) => { const moveX = e.changedTouches[0].clientX const moveY = e.changedTouches[0].clientY if (Math.abs(moveX - initX) > MIN_DISTANCE || Math.abs(moveY - initY) > MIN_DISTANCE) { clearTimeout(timer) timer = null copyBtn.hide() } }) element.addEventListener('touchend', () => { clearTimeout(timer) timer = null copyBtn.hide() }) }
上面的代码中定义了一个长按事件函数,可以通过监听 touchstart、touchmove、touchend 事件实现长按操作。其中 copyBtn 表示长按弹出框,可以通过该对象的 show()、hide() 方法实现显示和隐藏操作。在长按一定时间后显示弹出框,在移动操作或者松开时隐藏弹出框。
四、JS移动端事件
移动端与 PC 端的事件略有不同,移动端使用的事件更加丰富多彩,下面对 JS 移动端事件进行一些简单的介绍。
1. 触摸事件
触摸事件是移动端最基本的事件之一,其包含了如下 4 种事件:
- touchstart:手指放在屏幕上时触发
- touchmove:手指在屏幕上滑动时触发
- touchend:手指离开屏幕时触发
- touchcancel:触摸被中断时触发
2. 手势事件
手势事件是移动端的特色事件之一,既包含了触摸事件的三种基本事件,还包含了以下几种事件:
- gesturestart:多个手指触摸屏幕时触发
- gesturechange:多个手指在屏幕上移动时触发
- gestureend:多个手指离开屏幕时触发
3. 加速度事件
加速度事件是移动设备上的硬件事件,用于检测设备的运动状态和倾斜状态。
window.addEventListener('devicemotion', function(event) { console.log(event.acceleration.x) })
五、移动端手势事件
手势事件是移动端常见的一种事件,包含了各种手势,例如旋转、捏合、拖拽等。
1. 捏合手势
捏合手势是通过多指触摸实现的,用于实现类似于放大或缩小的操作。
let zoom = 1 let lastScale = 1 let scale = 1 let posX = 0 let posY = 0 let obj = document.getElementById('obj') obj.addEventListener('gesturestart', function(event) { lastScale = scale }) obj.addEventListener('gesturechange', function(event) { scale = lastScale * event.scale obj.style.transform = 'scale(' + scale + ') translate(' + posX + 'px,' + posY + 'px)' }) obj.addEventListener('gestureend', function(event) { lastScale = scale })
2. 旋转手势
旋转手势通过多指触摸实现,用于实现类似于旋转的操作。
let lastDegree = 0 let degree = 0 obj.addEventListener('gesturestart', function(event) { lastDegree = degree }) obj.addEventListener('gesturechange', function(event) { degree = lastDegree + event.rotation obj.style.transform = 'rotate(' + degree + 'deg) translate(' + posX + 'px,' + posY + 'px)' })
3. 拖拽手势
拖拽手势通过单指触摸实现,用于实现类似于拖拽的操作。
let startX = 0 let startY = 0 let offsetLeft = 0 let offsetTop = 0 obj.addEventListener('touchstart', function(event) { startX = event.touches[0].clientX startY = event.touches[0].clientY offsetLeft = obj.offsetLeft offsetTop = obj.offsetTop }) obj.addEventListener('touchmove', function(event) { let x = event.changedTouches[0].clientX - startX + offsetLeft let y = event.changedTouches[0].clientY - startY + offsetTop obj.style.left = x + 'px' obj.style.top = y + 'px' })
六、移动端 hover 事件
在 PC 端中,常见的交互方式之一就是鼠标 hover 事件,但这个事件在移动端中并不存在。但通过模拟 hover 事件,我们仍然可以在移动端中实现类似于 hover 的效果。
document.getElementById('btn').addEventListener('touchstart', function(e) { this.classList.add('hover') }) document.getElementById('btn').addEventListener('touchmove', function(e) { const rect = this.getBoundingClientRect() if (e.touches[0].clientX < rect.left || e.touches[0].clientX > rect.right || e.touches[0].clientY < rect.top || e.touches[0].clientY > rect.bottom) { this.classList.remove('hover') } }) document.getElementById('btn').addEventListener('touchend', function(e) { this.classList.remove('hover') })
通过添加和移除 class 属性,来模拟 hover 事件。当手指滑出按钮范围时,移除 hover 效果。
七、移动端拖拽事件
在移动端中,通过拖拽来实现交互,也是非常常见的一种方式。下面是一个简单的实现方法:
let dragItem = null let currentX = 0 let currentY = 0 let initialX = 0 let initialY = 0 let xOffset = 0 let yOffset = 0 document.addEventListener('touchstart', dragStart) document.addEventListener('touchend', dragEnd) document.addEventListener('touchmove', drag) function dragStart(e) { dragItem = e.target initialX = e.touches[0].clientX - xOffset initialY = e.touches[0].clientY - yOffset } function dragEnd(e) { initialX = currentX initialY = currentY dragItem = null } function drag(e) { if (dragItem !== null) { e.preventDefault() currentX = e.touches[0].clientX - initialX currentY = e.touches[0].clientY - initialY xOffset = currentX yOffset = currentY setTranslate(currentX, currentY, dragItem) } } function setTranslate(xPos, yPos, el) { el.style.transform = "translate3d(" + xPos + "px, " + yPos + "px, 0)" }
通过监听 touchstart、touchend、touchmove 事件,在 touchmove 事件中实时更新元素位置的坐标,设置 translate 值来实现拖拽效果。
八、移动端双击事件
移动端双击事件在实现缩放等操作时非常实用,下面是一个简单的双击事件实现方法:
let before = null let lastTap = null let currentScale = 1 obj.addEventListener('touchstart', function(event) { const now = Date.now() const delta = now - before const tap = event.touches[0].clientX + ',' + event.touches[0].clientY const doubleTap = lastTap && delta < 300 && tap === lastTap if (doubleTap) { currentScale = currentScale === 1 ? 2 : 1 setScale(currentScale) } lastTap = tap before = now }) function setScale(scale) { obj.style.transform = 'scale(' + scale + ') translate(' + posX + 'px,' + posY + 'px)' }
通过设置一个 before 变量来记录前一次点击的时间戳,通过计算两次点击的时间差,来判断是否