Safari里的touch事件解析

近两天有个项目,需求人想要实现像iphone系统里那样通过手势滑动来实现两个物体的交换,无奈这个东西想要在触屏手机上的浏览器上实现,我目前还是无能为力的,因为safari的API里确实没有这个event的,因为触屏手机上是没有mouse的相关事件的,虽然touch事件在一定程度上是封装了一些mouse事件的,但是touch事件还是有很多限制,没有mouse事件那么灵活。不过比较不错的倒是很有研究的价值,不过写这个的时候又有一点小灵感,需要做一些小实验去测试一番。期待今天没有活儿的话,就可以好好研究研究了。这都是闲话,现在切入主题。

safari里的touch事件包括touchstart,touchmove,touchend,touchcancel这四个事件, 其实熟悉鼠标事件的话就知道鼠标有mouseup,mousedown,mouseover,mouseout,mousemove这几个相关的事件,如果你做过鼠标的拖拽功能的话,就知道会涉及到鼠标的mouseover ,mousemove,mouseout这三个事件,那么这里相同的在safari的touch事件里基本就是对应的鼠标的这三个操作,只是不同的,iPhone等触屏界面中没有鼠标的呈现,但是基本原理是相当的。safari里会涉及一个手指one-finger操作,这里就会涉及touchstart、touchmove、touchdown这三个状态。one-finger操作在iphone,iTouch这些手持设备里是很重要的,可以实现一些很炫的效果,比如翻书的效果等等。

下面逐一介绍一下。

一、touchstart事件
当你把一个手指放到一个可点击的元素(如果为不可点击的元素的话,将不会触发此事件)上时,将会触发touchstart事件,表示touch事件的开始。在touchstart状态下我们可以获取touches集合,这个集合里包含的就是手指放上去后所点击的元素,这里只是one-finger事件,当然手指点击的对象就是touches[0]这个对象了,在这个状态下你可以对所点击的元素进行一些操作,通常使用最多的是对当前点击的元素的位移进行设置,因为很奇怪的是再iOS中对一个元素使用touch事件移动了一定的位移后,下次再点击的时候,此元素的位置还是回到了最开始的位置,相当于位移为0,那么在touchstart状态下在touchmove之前就设置元素的位移为上一次移动的位移,从而在操作上看是连续的。

二、touchmove事件
在对元素进行拖拽的时候起主要作用的就是touchmove事件了,可以在此环节实现元素的one-finger拖动跟随效果。主要会使用到的属性就是pageX和pageY获得当前手指的位置,然后利用和touchstart时的pageX和pageY的差值,采用translate或translate3d来实现元素的位移。

三、touchend事件
很容易理解,当我们把手指从元素上拿开的时候就会触发此事件,对于touch拖动效果的制作,此状态下,通常用于保存此次移动的位置,从而可以在下一次touchstart的时候将元素的位置还原成touchend时所在的位置了。

四、关于touch事件里涉及的一些属性介绍

(1) touches 数组对象 
当一根手指放到可点击的对象上时产生一个touch对象,测试了一下,即使两根手指同时放到一个对象上 去,会产生两个touch对象,也就是说,touch对象基本就代表手指的个数了,但必须是同一时刻的哦
属性名称                                      属性说明 
-------------------------------------------------------------------------
length                               touch对象的个数
item()                               这个函数暂时还不知什么作用,包含的时native code

(2) touch对象
touch对象是touches数组中的一员,其就是safari里定义的一个对象,但是这里这个对象不等同于实际触摸点击的html元素
属性名称                                          属性说明
--------------------------------------------------------------------------
pageX                                 相对于父元素的x坐标
pageY                                 相对于父元素的y坐标
clientX                                 相对于当前窗口的x坐标
clientY                                 相对于当前窗口的y坐标
identifier                              都是一些数字,用法暂时还不清楚
screenX                               相对于当前屏幕的x坐标
screenY                               相对于当前屏幕的y坐标
target                                  指代当前点击的对象

(3)targetTouches数组对象
对于targetTouches这个数组其实比touches数组更有用,因为它是针对绑定touch事件的元素来说的,简单来说二者的区别在于,如果页面中有多个元素都绑定了touch事件的话,如果使用两根手指同时分别点击这两个绑定了touch事件的元素,此时touches的长度为2,targetTouches的长度为1,这就很清楚的说明了两者的区别,即touches数组里包含的是同一时刻的所有手指个数,targetTouches数组里只包含当前绑定touch事件的元素上的手指个数,也就是说touches.length>=targetTouches.length

(4)changeTouches数组对象
changeTouches的是针对当前绑定touch事件的元素来所,发生变化的touch对象的集合,但其实际作用不大,正常情况下很少有用两个手指同时操作一个元素的,因为那没有意义,有意义的多个手指操作,那就是gesture事件了

(5)scale属性:表示放大倍数

(6)rotation属性:表示旋转的角度

(7)timeStamp:表示事件生成的日期和时间


五、注意事项

(1)对于DOM的操作,我们很多时候会借助jQuery这样的框架来进行操作,jQuery里有个非常棒的绑定事件的函数live(),这个函数的作用是,即使是元素是在之后新生成的,也可以对其添加相应的事件,但是很遗憾,目前的版本(1.5左右,1.6还未用过)里的live事件虽然可以绑定touchstart等事件,也可以触发相应的事件,但是事件里的event是无法获取touches对象的。切记!所以提醒一句,最好是采用传统的addEventListener来绑定touch事件,不过此种方法虽没有什么问题,但是没法实现live()函数的功能,也就是对后生成的元素无效。不过可以采取在其外边添加一个div或者其他元素,在此元素上绑定touch事件,而在touch事件触发后可以通过targetTouches等属性来获取真正触发的对象是谁,从而在一定程度上解决了这个问题。

(2)虽然touch事件是safari上边独有的事件,不过很多Android系统的手机也都可以正常支持,很容易理解啦,因为他们基本内置浏览器都是webkit内核的。


六、小例子
<!DOCTYPE html>
<html>
   <head>
      <title>测试touch</title>
      <meta charset=UTF-8>
      <meta http-equiv="Cache-Control" content="no-cache">
      <meta id="viewport" name="viewport" content="width=device-width; initial-scale=1.0; minimum-scale=1.0; maximum-scale=1.0">
      <link rel="apple-touch-icon" href="http://u1.sinaimg.cn/3g/image/upload/0/110/176/19509/64477c90.png" />
      <style>
             body,html{margin:0px;}
      </style>
      <script type="text/javascript"  src="js/jquery-1.5.2.js"></script>
      <script>
           $(document).ready(function(){
                 var stx=sty=etx=ety=curX=curY=0;
                $("#movediv2").get(0).addEventListener("touchstart",function(event){
                        stx=event.touches[0].pageX;
                        sty=event.touches[0].pageY;
                        event.targetTouches[0].target.style.webkitTransform =  'translate(' + (etx) + 'px, ' + (ety) + 'px)';
                     },false);
                $("#movediv2").get(0).addEventListener("touchmove",function(event){
                     event.preventDefault(); 
                     curX = event.targetTouches[0].pageX - stx+etx; 
                     curY = event.targetTouches[0].pageY - sty+ety;
                     event.targetTouches[0].target.style.webkitTransform =  'translate(' + (curX) + 'px, ' + (curY) + 'px)';
                },false);
               $("#movediv2").get(0).addEventListener("touchend",function(event){
                    etx=curX;
                    ety=curY;
                },false);   
           });
   </script>
   </head>
   <body>
      <div style="width:300px;height:200px;position:relative;background:pink;">
         <div  id="movediv1" style="width:200px;height:200px;background:yellow;float:left;position:left;"></div>
         <div  id="movediv2"  style="width:100px;height:100px;background:green;float:right;position:right;position:absolute;"></div>
      </div>   
   </body>
</html>


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值