移动端touch事件
- touchstart
- touchmove
- touchend
事件点透
mouse 事件在移动端可以执行,但是要注意点透问题
- 在移动端中,手指触碰时,如果有 touch 事件,会立即执行,
- 并记录触碰坐标,在一定时间延迟后(300ms以内),在该坐标上查找元素,如果元素有mouse事件,就执行。
可以使用
e.preventDefault();解决box.addEventListener("touchstart",(e)=>{e.preventDefault();box.style.display = "none";})
touchEvent 事件参数
touches 当前屏幕上的手指
- targetTouches 当前元素上的手指
- changedTouches 触发当前事件的手指列表
let box = document.querySelector("#box");document.addEventListener("touchstart",(e)=>{e.preventDefault();},{passive:false})box.addEventListener("touchmove",(e)=>{box.innerHTML = `当前屏幕上的手指个数:${e.touches.length}<br/>当前元素上的手指个数:${e.targetTouches.length}<br/>触发当前事件的手指个数:${e.changedTouches.length}`;});
划屏操作
和web端的鼠标拖拽是一个思路let wrap = document.querySelector("#wrap");let list = document.querySelector(".list");let startPoint = 0;let startPosition = 0;let translateY = 0;wrap.addEventListener("touchstart", (e) => {console.log(e.changedTouches[0])startPoint = e.changedTouches[0].pageY;startPosition = translateY;});wrap.addEventListener("touchmove", (e) => {let nowPoint = e.changedTouches[0].pageY;let disPoint = nowPoint - startPoint;translateY = startPosition + disPoint;list.style.transform = `translateY(${translateY}px)`;});
划屏的技巧
回弹动画幻灯片
- 当滑动距离超过 wrap.width*threshold 就进行切换,否则还是显示当前张
// ...let threshold = .3;//当滑动距离超过 wrap.width*threshold 就进行切换,否则还是显示当前张let wrapW = wrap.clientWidth;wrap.addEventListener("touchend", (e) => {// ...// 判断滑动的距离是多少,大于某个节点时,让它切换到上一张或下一张if (Math.abs(disPoint.x) > threshold * wrapW) {//需要进行切换now -= disPoint.x / Math.abs(disPoint.x);}//根据 now 重新计算位置translateX = -now * wrapW;list.style.transition = ".3s";list.style.transform = `translateX(${translateX}px)`;});
无缝滚动
前后各补一张卡,或者说直接赋值两个图片列表
{let wrap = document.querySelector("#wrap");let list = document.querySelector("#list");let navs = [...document.querySelectorAll(".nav a")];let startPoint = {};//记录摁下时手指坐标let startX = 0;//记录摁下时元素位置let translateX = 0; //记录元素位移值let now = 0;//记录当前显示的时第几张let threshold = .3;//当滑动距离超过 wrap.width*threshold 就进行切换,否则还是显示当前张let wrapW = wrap.clientWidth;list.innerHTML += list.innerHTML;wrap.addEventListener("touchstart", (e) => {list.style.transition = "none";let touches = e.changedTouches[0];startPoint = {x: touches.pageX,y: touches.pageY};if (now === 0) { //第0组的第0张now = navs.length; //第1组第0张} else if (now === navs.length * 2 - 1) {//第1组最后一张now = navs.length - 1;//第0组最后一张;}translateX = -now * wrapW;list.style.transform = `translateX(${translateX}px)`;startX = translateX;});wrap.addEventListener("touchmove", (e) => {let touches = e.changedTouches[0];let nowPoint = {x: touches.pageX,y: touches.pageY};let disPoint = {x: nowPoint.x - startPoint.x,y: nowPoint.y - startPoint.y};translateX = startX + disPoint.x;list.style.transform = `translateX(${translateX}px)`;});wrap.addEventListener("touchend", (e) => {let touches = e.changedTouches[0];let nowPoint = {x: touches.pageX,y: touches.pageY};let disPoint = {x: nowPoint.x - startPoint.x,y: nowPoint.y - startPoint.y};// 判断滑动的距离是多少,大于某个节点时,让它切换到上一张或下一张if (Math.abs(disPoint.x) > threshold * wrapW) {//需要进行切换now -= disPoint.x / Math.abs(disPoint.x);}//根据 now 重新计算位置translateX = -now * wrapW;list.style.transition = ".3s";list.style.transform = `translateX(${translateX}px)`;navs.forEach(item => {item.classList.remove("active");});navs[now % navs.length].classList.add("active");});}
滑动方向的处理
上下左右滑动可能会产生冲突,设置为只能同时滑动一个方向
- 当用户想要进行左右滑动时,就只是左右可以滑动(禁止上下滑动)
- 当用户,想要进行上下滑动时,把左右滑动禁止了
- 当滑动方向一旦判定,则滑动过程中就一直认定用户想要做该方向的滑动,知道下次再触发滑动时,重新判断。
let isDir = false; // 判断用户是否认定方向let isMove = true;// 判读是否进行幻灯片切换wrap.addEventListener("touchmove", (e) => {// ...if (!isDir) {if (Math.abs(disPoint.x) - Math.abs(disPoint.y) > 5) {//console.log("左右滑动");isDir = true;} else if (Math.abs(disPoint.y) - Math.abs(disPoint.x) > 5) {//console.log("上下滑动");isDir = true;isMove = false;}}if (isMove) {isDir && (translateX = startX + disPoint.x);isDir && (list.style.transform = `translateX(${translateX}px)`);e.preventDefault();}});
阻止默认事件
如果要给 document、html、body这些元素的touch事件中阻止默认事件,一定记得设置,passive:false (允许阻止默认事件)
let box = document.querySelector("#box");box.addEventListener("touchstart",(e)=>{box.style.display = "none";});document.body.addEventListener("touchstart",(e)=>{e.preventDefault();},{passive: false});
阻止 touchstart 默认事件带来的影响
- 默认双指缩放被禁止
- 滚动条被禁止
- 鼠标事件被禁止(包括a标签的href)
- 禁止长按菜单弹出
- 阻止元素获得焦点和失去焦点
阻止 touchmove 默认事件带来的影响
- 默认双指缩放被禁止
- 滚动条被禁止
