背景:
在h5页面,实现长按弹出上拉菜单,我们知道h5没有所谓的长按事件,有些UI组件库封装了长按事件,比如zepto的longtap
在pc端有鼠标事件(mousedown,mousemove,mouseup),在h5有touch触摸事件(touchstart,touchmove,touchend)
不能因为需要一个长按事件就引入一个库,这里我们就基于touch触摸事件来实现。
touch事件群
手指快速点击一个元素,会经过:touchstart -> touchend --> click
手指长按一个元素,会经过:touchstart -> touchend
手指滑动,会经过:touchstart -> touchmove(n次) -> touchend
综上:
1、click事件发生在touchstart和touchend之后,这也就是我们所说的移动端点击事件一般有300ms的延迟(可用tap事件替代)
2、长按的过程是touchstart之后touchend之前,区分长按还是点击,可以根据时间判断,比如大于500ms是长按,小于500ms是点击
3、如果在点击屏幕的时候手指滑动的话,是不会触发click事件的
由以上结论,我们就可实现长按事件
主要逻辑:
1、在touchstart里定义延迟器,500ms后执行长按逻辑
2、在touchend里取消延迟器,即在touchstart触发的500ms之内,如果手指从屏幕上移开,则不是长按
3、在touchmove里取消延迟器,即如果手指在屏幕上滑动,则不是长按
代码如下:
注意:
1、H5页面长按会触发系统的默认事件,ios和安卓表现不同,如下图。可以使用event.preventDefault()方法阻止后面默认事件的发生
在touchstart中preventDefault,会导致click事件不触发和a链接点击没反应。可以使用tap代替click,但是a标签的话就不太方便了
在touchmove中preventDefault,会阻止浏览器默认滚动
2、在某些手机,比如vivo,没有move,但是touchmove事件仍然会触发
在这种情况,可以根据touch的位置判断手指是否移动,来区分是点击长按或者是滑动
在touchstart事件中记录touch时的x,y的坐标,然后在touchmove中,再判断touch的位置是否和touchstart中的一样的。
注意,查看TouchEvent最好在谷歌模拟手机浏览器中查看,不要在真实手机浏览器查看,本人在真实手机浏览器console和alert都看不到详细的信息,疑惑了半天,发现真实手机浏览器虽然看不到信息,但是可以直接取值(TouchList是类数组对象)
触屏事件的操作信息都存储在TouchEvent类型对象中,此对象属性较多,下面着重介绍下touches、targetTouches与changedTouches
touches[只读]:手指触摸到屏幕上,所有触摸点的集合;
targetTouchs[只读]:手指触摸到DOM元素(绑定事件的dom节点)上的触摸点的集合
changeTouches[只读]:表示自上次触摸事件以来发生改变的(和触摸事件对应的Touch 对象)
对于 事件, changedTouches是此次事件中新增加的触点。
对于
是刚从触摸面离开的触点(最后一次离开屏幕的手指的Touch 对象)
下图中有两个div,只对DIV2绑定了touchstart事件
当手指第一次触摸到DIV2时,三个对象表示的都是一样的;
再放下第二根手指和第三根手指同时触摸DIV1和DIV2时,
此时touches对象表示的是第一根手指、第二根手指、第三根手指的信息
此时targetTouches对象表示的是第一根手指和第三根手指的信息,因为绑定touch事件的节点为DIV2
而changedTouches对象表示的是第二根手指和第三根手指的信息,因为第一根手指没有变化
综上:
touchmove时,如果手指从目标元素(绑定事件的dom节点)滑出,targetTouches还会有此触摸点信息
当一个触摸点从目标元素离开,它的信息将从 touches、targetTouches里移除,但是changedTouches会保留此触摸点信息;
当最后一个触摸点离开,touches、targetTouches变成空值,而changedTouches保留着最后一个离开的触摸点信息
扩展:
Touch.screenX:触点相对于屏幕左边沿的X坐标。只读属性。
Touch.screenY:触点相对于屏幕上边沿的Y坐标。只读属性。
Touch.clientX:触点相对于可见视区(visual viewport)左边沿的X坐标。不包括任何滚动偏移。只读属性。
Touch.clientY:触点相对于可见视区(visual viewport)上边沿的Y坐标。不包括任何滚动偏移。只读属性。
Touch.pageX:触点相对于HTML文档左边沿的X坐标。当存在水平滚动的偏移时,这个值包含了水平滚动的偏移。只读属性。
Touch.pageY:触点相对于HTML文档上边沿的Y坐标。当存在水平滚动的偏移时,这个值包含了垂直滚动的偏移。只读属性。
如需转载,请注明文章出处和来源网址:http://www.divcss5.com/html/h62775.shtml