您的位置:首页 > 其它

触摸事件

2016-03-15 00:57 197 查看

一、Touch(触摸或叫接触)

Touch到底是什么东西呢?Touch是一个接口(在javascript中你可以认为它就是一个对象),一个包含着能响应触摸的设备上的一个接触点信息的对象,通常是手指和触笔与触摸屏或者触摸板的一次接触。它有三个属性Touch.radiusX、Touch.radiusY和Touch.rotationAngle,用来描述这个近似椭圆的接触点,Touch.radiusX是椭圆水平半径,Touch.radiusY则是垂直半径,Touch.rotationAngle是旋转角度。它们是用来描述接触点区域的,这个不是数学里的点(没有大小,只有坐标),这个点有大小,比如手指点击的可能大些,触笔点击的则小些,当然这些属性同时也依赖于硬件,差别很大。
注意:上述三个属性还处于草案中,并不在TouchEvents规范里,并且没有没有被广泛实现,浏览器支持情况都还是未知的。下方(参见testTouch子文档)是个简单例子,可惜结果是undefined。
constructor:Touch(),用于产生一个接触点对象,它没有父类,自然也没有继承或实现其他任意属性,同时它也没有本身的方法。
Touch对象的自己的一些属性如下:

1. Touch.identifier:每次触摸都有一个唯一的标识,从开始到结束(移除触摸面板),中间可能有move(移动),这个标识都不变,这样确保你一次触摸,特别是在多点             触摸轨迹跟踪时很有用。
2. Touch.screenX:接触点相对于screen(屏幕)左边缘的X坐标。

3. Touch.screenY:接触点相对于screen(屏幕)上边缘的Y坐标。

4. Touch.clientX:接触点相对于viewport(浏览器视图窗口)的左边缘的X坐标,不包括任何滚动偏移。

5. Touch.clientY: 接触点相对于viewport(浏览器视图窗口)的上边缘的Y坐标,不包括任何滚动偏移。

6. Touch.pageX: 接触点相对于document(文档)左边缘的X坐标,和Touch.clientX不一样,这个包括滚动偏移量。

7. Touch.pageY:接触点相对于document(文档)上边缘的Y坐标,和Touch.clientY不一样,这个包括滚动偏移量。

8. Touch.target:接触点开始(第一个放置位置)所在的元素,尽管接触点滑到其他元素或者移除文档了,这个target都不变。
9. Touch.force:接触时施加的压力,只读属性,和radiusX等三个属性以及constructor一样,草案中,未可靠。

Touch的这些属性均为只读属性。。。。。本来打算弄个表格来着,不知道是我不会用CSDN编辑器的表格还是确实就那么丑,总之是不弄表格了。。。以及行间距怎么设置来着???
每个Touch都可用位置,大小、形状、压力和目标(target)来描述,MDN上描述为:The Touch interface represents a single contact point on a touch-sensitive device.即代表触摸设备上的单个接触点,总觉得不太恰当。个人理解认为它是一次接触,并不是一个接触点,这一次接触在触摸板上滚来滑去都还是这个Touch本身,只是状态改变了而已。一组Touch就用TouchList对象来表示。

二、TouchEvent (触摸事件)

TouchEvent代表一个事件(接触或者触摸状态改变时触发的一个事件),一个或者多个接触点的接触、移动、移除以及增加接触点等都会触发这样一个事件。其构造函数TouchEvent()用于产生一个TouchEvent对象。这个接口继承于UIEvent和Event,当然也继承了它们的属性。

1. TouchEvent.altKey:返回一个布尔型的值,表示这个事件触发时,alt键是否被按下,是则true,否则false。
2. TouchEvent.changedTouchs:一组Touch的TouchList对象,这个list里存放的是自上次触发TouchEvent和本次之间状态有所改变的Touch。比如:同时放三手指触屏,该list     的长度就是3,先放一个手指触屏,再放一个手指触屏,那就是触发两次TouchEvent事件,每次触发时list的长度都是1.
3. TouchEvent.ctrlKey:返回一个布尔类型的值,表示触发此事件时ctrl键是否被按下,是则true,否则false。
4. TouchEvent.metaKey:返回一个布尔型值,表示触发此事件时meta键是否被按下,是true否false。
5. TouchEvent.shiftKey:返回一个布尔型值,表示触发此事件时shift键是否被按下,是true否false。
6. TouchEvent.targetTouches:返回一个TouchList,TouchList中的Touch是当前接触着屏幕并且它们的target是同一个目标。相当于是获取到和触发此TouchEvent的Touch同       源的当前Touch列表。
7. TouchEvent.Touches:返回一个TouchList,忽略它们是否同源(target)忽略它们是否状态改变,只要当前接触着屏幕就包含在里面。

Touch Event types (事件类型)

有几种类型的触摸事件用来表示触摸相关的改变已经发生,你可以通过TouchEvent.type来判断具体是发生什么改变。

1. touchstart

当用户放置接触点的时候被触发,Touch的target也是这时指定的,这次触摸过程中这个target都不会变,同时这个Touch的identifier也不会随着Touch状态的变化而变化。

2.touchend

当用户抬起手指(触笔)或者将手指移除触摸板之外时触发,这次Event的target——即Touch.target还是该Touch在touchstart时确定的那个element,即使移除屏幕了也不会变。touchend发生后的Touch可以在Touch.changedTouches里找到(个人觉得这一点貌似有点不确定)。

3.touchmove

当用户在触摸板上移动接触点时触发,当Touch的radius、rotation angle或者force属性改变时也会触发。

注意:touchmove事件触发平率是浏览器规范,依赖于浏览器,不能依赖于这个时间间隔。

4.touchcancel

当接触点被某种意外扰乱时触发,这意外情况和硬件设备有关,和浏览器也有关,比如:

意外事件的发生取消了Touch,比如alert事件;

接触点离开了文档窗口并移入浏览器的UI区域、插件区域或者其他扩展区域;

用户增加接触点(超过设备所能支持的个数)时,TouchList中最早的Touch被取消掉。

注意:很多情况下Touch和鼠标事件会同时触发,目的是让用户能和没有触摸特性的应用交互。如果你要用Touch Event,那你应该使用event.preventDefault()来阻止鼠标事件继续被处理。

GlobalEventHandlers
目前还是实验性的技术,不稳定,有望在将来的版本中得到规范。比如:

GlobalEventHandlers.ontouchstart 是touchstart的全局处理器;

GlobalEventHandlers.ontouched 是touchend的全局处理器;

GlobalEventHandlers.ontouchmove是touchmove的全局处理器;

GlobalEventHandlers.ontouchcancel是touchcancel的全局处理器。

浏览器支持情况:



三、关于preventDefault()

有种技巧(说法)是在第二次Touch中调用preventDefault()来阻止页面伸缩行为,这里的第二次Touch应该是TouchList中除了第一次以外的Touch,然而这个第一次可以是其中任意一个。换句话说:在多个Touch存在的情况下,TouchEvent发生的时候,只能有一个Touch不用调用preventDefault函数。其实这样并不好处理,因为preventDefault是Event的成员,Touch并没有这个函数,并且这种行为并不是Touch
Event规范,不同浏览器的行为也不同,故极不推荐使用这种方式,而是应该在meta的viewport里阻止拉伸缩放行为。

四、Event Order

一个典型的顺序:

1.touchstart

2.0次或多次touchmove

3.touchend

4.mousemove

5.mousedown

6.mouseup

7.click

如果交互过程中touchstart、touchmove或者touchend事件被取消了,那么鼠标事件就不会被触发了。

五、判断是否支持触屏

1.目前而言,ontouchsart、ontouchmove和ontouchcancel都还是实验性事件,并没有被标准化,所以不推荐单独使用。

2.Document.createTouch()目前已经从标准规范中移除了,虽然还有浏览器支持,但是已经不能依赖于它了。

3.useragent判断:
<span style="font-size:18px;">var isTouch = !!ua.match(/AppleWebkit.*Mobile.*/) || 'ontouchstart' in window;</span>

这对于有些设备或许不太准确,但已经能够判断大部分的设备了。

4.媒体查询,@media (pointer:***),“***”的可能取值:none、coarse、fine:
none:表示设备主要输入机制不包括定点输入(鼠标和触屏都没有)
coarse:有限精确度的定点输入设备,即定点模糊的输入机制。即表示触屏一类的输入设备。个人测试,非触摸电脑上Firefox为false,chrome46为false,触屏手机上为true。
fine:具有精确定点输入的设备。指鼠标、触摸板、触笔一类的。但个人测试,非触摸电脑上Firefox为false,chrome46为true,触屏手机上为false。

这些个判断都有一些缺陷,那我们可以组合一下来判断:

var isTouchScreen = !!navigator.userAgent.match(/AppleWebkit.*Mobile.*/) || "ontouchstart" in window ||
(window.matchMedia ? matchMedia("(pointer:coarse)").matches || !!matchMedia("-moz-touch-enabled").matches : false);

其中!!matchMedia("-moz-touch-enabled").matches是专门为判断Firefox而添加的,如果支持Touch Event结果为1,否则为0,对于其他浏览器都可能不支持。

整理的MDN的例子可以到TouchEvent_demo下载。
文章有错误之处,还请指正,谢谢!

参考文献:
https://developer.mozilla.org/en-US/docs/Web/API/Touch_events#Example

https://www.w3.org/TR/mediaqueries-4/#mf-interaction

https://developer.mozilla.org/en-US/docs/Web/API/Touch

https://developer.mozilla.org/en-US/docs/Web/CSS/:-moz-system-metric%28touch-enabled%29
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Touch Event 触摸 事件