-
-
touchstart 当刚刚触摸屏幕的时候触发
-
touchmove 在屏幕上来回的滑动的时候触发
-
touchend 离开屏幕的时候触发
-
touchcancel 被迫终止触摸的时候触发 (例如:来电 消息弹窗)
<div class="box"></div> <script> var box = document.querySelector('.box'); /*1 touchstart 当刚刚触摸屏幕的时候触发 */ box.addEventListener('touchstart', function (e) { console.log('touchstart'); console.log(e); }); /*2 touchmove 在屏幕上来回的滑动的时候触发*/ box.addEventListener('touchmove', function (e) { console.log('touchmove'); }); /*3 touchend 离开屏幕的时候触发*/ box.addEventListener('touchend', function (e) { console.log('touchend'); console.log(e); }); /*获取触摸点坐标*/ /*1. clientX/Y 记录的是基于视口的坐标*/ /*2. pageX/Y 记录的是基于页面的坐标*/ /*3. screenX/Y 记录的是基于屏幕的坐标*/ /*不管什么坐标都可以 需要的是位置的改变 */ </script>
tap
事件是依据touches
组来封装的:
自己封装的tap
事件:
var tap = function(dom,callback){ //判断是否滑动过 var isMove = false; //记录响应的速度 var time = 0; dom.addEventListener('touchstart',function(e){ time = Date.now(); console.log(e); }); dom.addEventListener('touchmove',function(e){ isMove = true; }); dom.addEventListener('touchend',function(e){ var respondTime = Date.now() - time; /*tap*/ if(!isMove && respondTime < 150){ /*满足条件*/ callback && callback(); } //重置 isMove = false; }); } var box = document.querySelector('.box'); tap(box, function(){ // your code... console.log('tap触发了'); });
HTMLElement.prototype.myTap = HTMLElement.prototype.myTap || function (callBack) { // myTapStart --- touchstart事件时间戳 // myTapEnd --- 获取touchend事件时间戳 // timeTap --- myTapStart - myTapEnd <= timeTap 时,被认为触发 tap 事件 let myTapStart = 0, myTapEnd = 0, timeTap = 300; // 监听 touchstart 事件 this.addEventListener('touchstart', function (e) { // 获取touchstart事件的时间戳 myTapStart = e.timeStamp; // changedTouchs 是事件对象 TouchEvent 上面的属性,上面存储了一个当前操作的信息。 let point = e.changedTouches[0]; this.strX = point.pageX; this.strY = point.pageY; // 锁死 touchmove 事件 this.isMove = false; }, false); // 监听 touchmove 事件 this.addEventListener('touchmove', function (e) { let point = e.changedTouches[0]; let changeX = point.pageX - this.strX; let changeY = point.pageY - this.strY; if (Math.abs(changeX) > 10 || Math.abs(changeY) > 10) { this.isMove = true; } }, false); // 监听 touchend 事件 this.addEventListener('touchend', function (e) { // 获取 touchend 事件的时间戳 myTapEnd = e.timeStamp; const isTimeTap = myTapEnd - myTapStart; if (!this.isMove && isTimeTap <= timeTap) { callBack(); } }, false); }; let box = document.querySelector(".box"); box.myTap(function () { // your code... console.log("单击事件myTap"); });
HTMLElement.prototype.doubleTap = HTMLElement.prototype.doubleTap || function (callBack) { // isTouchEnd // lastTime // lastTx lastTy --- 合理范围内的误差 // firstTouchEnd --- 第一次 触发 touchend 事件 // body --- iphone os // dTapTimer --- 定时器 // startTx startTy --- 获取 touchstart 的位置 // startTime --- 兼容 iphone os let isTouchEnd = false, lastTime = 0, lastTx = null, lastTy = null, firstTouchEnd = true, body = document.body, dTapTimer, startTx, startTy, startTime; // 监听 touchstart this.addEventListener('touchstart', function (e) { // 清除定时器s if (dTapTimer) { console.log('dTapTimer'); clearTimeout(dTapTimer); dTapTimer = null; } // 获取 touchstart 的位置 const touches = e.touches[0]; startTx = touches.clientX; startTy = touches.clientY; }, false); // 监听 touchend this.addEventListener('touchend', function (e) { const touches = e.changedTouches[0], endTx = touches.clientX, endTy = touches.clientY, now = Date.now(), duration = now - lastTime; // 首先要确保能触发单次的 tap 事件 if (Math.abs(startTx - endTx) < 6 && Math.abs(startTx - endTx) < 6) { console.log('单次点击的 touchstart 的位置和 touchend 的位置允许 6px 的误差'); // 两次 tap 的间隔确保在 500 毫秒以内 if (duration < 501) { // 本次的 tap 位置和上一次的 tap 的位置允许一定范围内的误差 if (lastTx !== null && Math.abs(lastTx - endTx) < 45 && lastTy !== null && Math.abs(lastTy - endTy) < 45) { firstTouchEnd = true; lastTx = lastTy = null; callBack() } } else { lastTx = endTx; lastTy = endTy; } } else { firstTouchEnd = true; lastTx = lastTy = null; } // 获取上一次点击的时间戳 lastTime = now; }, false); // 在 iOS 的 safari 上手指敲击屏幕的速度过快, // 有一定的几率会导致第二次不会响应 touchstart 和 touchend 事件 // 同时手指长时间的touch不会触发click if (navigator.userAgent.toLowerCase().indexOf('iphone os')) { console.log('iphone os'); body.addEventListener('touchstart', function (e) { startTime = Date.now(); }, true); body.addEventListener('touchend', function (e) { let noLongTap = Date.now() - startTime < 501; if (firstTouchEnd) { firstTouchEnd = false; if (noLongTap && e.target === this) { dTapTimer = setTimeout(function () { // 永远不会执行setTimeout里面的代码,因为在 click 中清除了 dTapTimer firstTouchEnd = true; lastTx = lastTy = null; console.log('fire double tap event at iphone os'); callBack() }, 400); } } else { firstTouchEnd = true; } }, true); // iOS 上手指多次敲击屏幕时的速度过快不会触发 click 事件 body.addEventListener('click', function (e) { if (dTapTimer) { clearTimeout(dTapTimer); dTapTimer = null; firstTouchEnd = true; } }, false); } } let box = document.querySelector('.box') box.doubleTap(function() { console.log('doubleTap 触发了') })
<script> HTMLElement.prototype.longTap = HTMLElement.prototype.longTap || function (callBack) { let startTx, startTy, lTapTimer; this.addEventListener('touchstart', function (e) { // 清除定时器 if (lTapTimer) { clearTimeout(lTapTimer); lTapTimer = null; } // 获取 touchstart 位置 let touches = e.touches[0]; startTx = touches.clientX; startTy = touches.clientY; lTapTimer = setTimeout(function () { callBack() console.log('fire long tap event'); }, 1000); e.preventDefault(); }, false); this.addEventListener('touchmove', function (e) { // 获取 touchmove 位置 let touches = e.touches[0], endTx = touches.clientX, endTy = touches.clientY; // 定时器存在 并且 发生了 touchmove 清除定时器 if (lTapTimer && (Math.abs(endTx - startTx) > 5 || Math.abs(endTy - startTy) > 5)) { clearTimeout(lTapTimer); lTapTimer = null; } }, false); this.addEventListener('touchend', function (e) { if (lTapTimer) { clearTimeout(lTapTimer); lTapTimer = null; } }, false); } let box = document.querySelector('.box') box.longTap(function() { // your code ... console.log('longTap 触发了') })
HTMLElement.prototype.swipe = HTMLElement.prototype.swipe || function (callBack) { let isTouchMove, startTx, startTy; this.addEventListener('touchstart', function (e) { let touches = e.touches[0]; startTx = touches.clientX; startTy = touches.clientY; isTouchMove = false; }, false); this.addEventListener('touchmove', function (e) { isTouchMove = true; e.preventDefault(); }, false); this.addEventListener('touchend', function (e) { if (!isTouchMove) { return; } let touches = e.changedTouches[0], endTx = touches.clientX, endTy = touches.clientY, distanceX = startTx - endTx distanceY = startTy - endTy, isSwipe = false; if (Math.abs(distanceX) >= Math.abs(distanceY)) { if (distanceX > 20) { callBack('left') console.log('fire swipe left event'); isSwipe = true; } else if (distanceX < -20) { callBack('right') console.log('fire swipe right event'); isSwipe = true; } } else { if (distanceY > 20) { callBack('up') console.log('fire swipe up event'); isSwipe = true; } else if (distanceY < -20) { callBack('down') console.log('fire swipe down event'); isSwipe = true; } } if (isSwipe) { console.log('fire swipe event'); } }, false); } let box = document.querySelector('.box') box.swipe(function (direct) { // your code ... console.log('swipe 触发了' + direct) })