- 为什么移动端不用click
移动端的click有300ms延迟的问题,在移动端浏览器中,连续两次点击是缩放操作,所以在用户点击屏幕后,浏览器会检查在300ms内是否有另一次点击,如果没有则触发click事件,所以移动端不用click - 替换click的方案
1.使用touchstart
touch事件包括touchstart、touchend、touchmove等,简单使用touchstart来替换click,但问题是,如果我想在同一对象上绑定一个单击事件和一个滑动事件怎么办,这时候就会出现冲突。
2.使用tap事件
标准事件中没有tap事件,tap事件是一些库,如zepto,使用touch进行封装的,在touchstart、touchend时记录时间、手指位置,在touchend时进行比较,如果手指位置为同一位置且时间间隔较短,且过程中未曾触发touchmove事件,则调用回调函数。
zepto用于判断的关键代码:
//延迟时间
if (delta > 0 && delta <= 250) touch.isDoubleTap = true;
//允许的偏移量
if (deltaX < 30 && deltaY < 30) {……}
不过300ms后还是会产生click事件,只是在该对象上没有进行监听,由此产生了“点透”现象:
(1)页面弹出一个模态框,模态框上有个按钮(关闭模态框),按钮正下方(在主页面上)有一个输入框
(2)当点击模态框上的关闭按钮,模态框立即消失,但300ms后click事件触发,而输入框正好监听click事件,因此输入框会得到焦点
为什么不对click进行拦截呢?原因是zepto使用的是事件代理,元素上的touch事件冒泡到document上,在document的事件回调中执行绑定在元素上的事件回调,而在document上执行preventDefault是不起作用的。
3.使用fastclick
fastclick也是使用事件委托(FastClick.attach(document.body, options);),但是冒泡到body上后,通过tap原理来判断是否单击,是则重新构造一个点击事件dispatch到原来的元素上,触发元素上的绑定事件,由于在tap事件后触发click,所以解决了延迟问题,并且300ms后,不再产生click事件,所以解决了”点透“问题。
FastClick.prototype.sendClick = function(targetElement, event) {
……
clickEvent = document.createEvent('MouseEvents');
clickEvent.initMouseEvent(this.determineEventType(targetElement),
true, true, window, 1, touch.screenX, touch.screenY, touch.clientX, touch.clientY, false, false, false, false, 0, null);
clickEvent.forwardedTouchEvent = true;
targetElement.dispatchEvent(clickEvent);
};
到了这里,我们知道,最好的解决兼容PC和移动端的点击事件的办法是引入fastclick。然而我现在想要实现的是各种触摸事件——gg——既然要实现各种触摸事件,那就暂时不考虑PC的问题,所以考虑使用hammer.js
hammer.js
使用hammer.js实现qq消息中拖出删除画面的效果
在vue中使用hammer.js
使用方法:
<div v-touch:panleft="onPanLeft" v-touch:panright="onPanRight">
事件对象
TouchEvent 是一类描述手指在触摸平面(触摸屏、触摸板等)的状态变化的事件。这类事件用于描述一个或多个触点,使开发者可以检测触点的移动,触点的增加和减少,等等。
每 个 Touch对象代表一个触点; 每个触点都由其位置,大小,形状,压力大小,和目标 element描述。 TouchList 对象代表多个触点的一个列表
1) TouchEvent
TouchEvent的属性继承了 UIEvent和 Event。
三个重要属性:
TouchEvent.changedTouches: 一个 TouchList 对象,包含了代表所有从上一次触摸事件到此次事件过程中,状态发生了改变的触点的 Touch 对象。
TouchEvent.targetTouches: 一个 TouchList 对象,是包含了如下触点的 Touch 对象:触摸起始于当前事件的目标 element 上,并且仍然没有离开触摸平面的触点。
TouchEvent.touches: 一 个 TouchList 对象,包含了所有当前接触触摸平面的触点的 Touch 对象,无论它们的起始于哪个 element 上,也无论它们状态是否发生了变化。
2) TouchList详解
只读属性:length返回这个TouchList中Touch对的个数。(就是有几个手指接触到了屏幕)
方法:item(index)返回TouchList中指定索引的Touch对象
3) Touch详解
touch类事件
- 事件基础
触摸事件,有touchstart touchmove touchend touchcancel 四种之分
1.touchstart:手指触摸到屏幕会触发
当用户手指触摸到的触摸屏的时候触发。事件对象的 target 就是touch 发生位置的那个元素。
2.touchmove:当手指在屏幕上移动时,会触发
当用户在触摸屏上移动触点(手指)的时候,触发这个事件。一定是先要触发touchstart事件,再有可能触发 touchmove 事件。 3.touchmove 事件的target 与最先触发的 touchstart 的 target 保持一致。touchmove事件和鼠标的mousemove事件一样都会多次重复调用,所以,事件处理时不能有太多耗时操作。不同的设备,移动同样的距离 touchmove 事件的触发频率是不同的。 有一点需要注意:即使手指移出了 原来的target 元素,则 touchmove 仍然会被一直触发,而且 target 仍然是原来的 target 元素。
4.touchend:当手指离开屏幕时,会触发。
当用户的手指抬起的时候,会触发 touchend 事件。如果用户的手指从触屏设备的边缘移出了触屏设备,也会触发 touchend 事件。5.touchend 事件的 target 也是与 touchstart 的 target 一致,即使已经移出了元素。
6.touchcancel:可由系统进行的触发(如电话接入或者弹出信息),比如手指触摸屏幕的时候,突然电话来了,或者系统中其他打断了touch的行为,则可以触发该事件。