项目中须要用到手机拖动事务,但对于pc浏览器的mousedown、mou搜刮引擎优化ver和mouseup手机支撑没有pc好,所有搜了一篇关于iphone上的触摸和手势来进修进修。
以下为原文:
我先来说说iPhone的把握台,因为我发明它在测试时是很是首要的。在Settings-Safari-Developer下,你可以把它打开或 封闭。它供给了一些简单的信息,包含错误、警告等。
当我浏览这份[Apple Developer Connection page]文档之后,固然它写的很活泼和完全,但仍 然给我留下了一些细节上的困惑。并且,若是你不是ADC(Apple开辟者中间)的会员,看这个文档可能会让你更含混。
清理思路
Apple给API加了两个新设法:触摸(touch)和手势(gesture)。触摸用来记录你有几许手指放在屏幕上、它们都在哪里、它们在做什 么操纵以及它们的轨迹。手势来检测你在用两个手指做什么,是否在捏(pinching)、推(pushing)、或是在扭转(rotating)。
触摸
当你把一根手指头放在屏幕上时,触摸(touch)事务便被触发了。每当一根新的手指放在屏幕上,就会触发一个新的touchstart事务。而当 手指抬起分开屏幕,touchend事务便被触发了。若是在手指接触屏幕后,你又挪动了这根手指,那么触发的是touchmove事务。
有以下touch事务:
- touchstart: 手指放在屏幕上时触发
- touchend: 手指分开屏幕时触发
- touchmove: 手指在屏幕上移动时触发
- touchcancel: 体系可以作废touch事务,但我不断定它如何才干触发。我想可能是当你拖放时,接到一个类似短信或者其它事务时,才会触发。但我没有测试成功过。
node.ontouchstart = function(evt){
console.log(evt.pageX + "/" + evt.pageY);
// 哦不! 值都是空的,必然有BUG
}
我的第一个错误,产生在监听这些事务并试着获得这些事务的坐标(pageX, pageY等)时。在再一次看了ADC的文档后,我懂得了这三个事务依附于对象。但我不克不及十分断定,所以我去测试、记录、实验。
它帮助我解决了Apple开辟者们一向感觉棘手的题目。在应用鼠标时,你实际上只产生一个点:经由过程鼠标指针。当你用手时,你可以用两个手指,当你击 打(tap)屏幕右侧时,另一只手指可以放在屏幕左侧。
我们的事务对象有一个列表,这个列表包含了每个接触屏幕的手指所产生的信息。它还包含了另两个列表,一个只包含来自雷同节点的手指信息,另一个只包 含与当前事务相干的手指信息。每一个touch事务都邑激活这些列表。
下面就是这个列表:
- touches: 每个接触屏幕的手指所产生的信息
- targetTouches: 和touches类似,但它过滤出只来自雷同节点的手指信息
- changedTouches: 只包含与当前事务相干的每个手指信息(见下文)
要更好地懂得这些列表,让我们来快速浏览一些例子吧:
- 当我把一根手指放在屏幕上,3个列表都是雷同的信息。它会在changedTouches中,因为手指放上去就会触发这个事务。
- 当我放上第二根手指,touches会变为两项,每一根手指都有一项。只当第二根手指放在第一根手指地点节点上时,targetTouches才 会变成两 个项。changedTouches的信息和第二根手指有关,因为它触发了事务。
- 当我刚巧在同一时刻放上两根手指时,changedTouches才可能会有两个项目,每根手指一个。
- 若是我移下手指,独一会改变的列表是changedTouches并且会包含多个移下手指的信息(起码有一个)。
- 当我抬起一根手指,它会从touches、targetTouches中移除,同时它会呈如今changedTouches中,因为它又触发了这 个事务。
- 移除最后一根手指,会清空touches和targetTouches,changedTouches会包含最后一根手指的信息。
有了这个列表,我可以对用户的操纵对峙亲近的监控。想象一下,用JavaScript发明(另)一个Super Mario的克隆版本。我可以告诉用户,他(她)的拇指在一个什么标的目标上,同时也可以监控用户的跳跃或发射****弹。
正如我之前所说,这些列表包含了手指触摸屏幕时的信息。这些对象都很是类似,就像你凡是看到的那样,在一个事务对象转到一个事务处理惩罚器时,一组有限 的属性可以用在这些对象上。下面是这些对象上属性的完全列表:
- clientX: touch事务相对于视图(viewport)的X轴坐标(不包含迁移转变位移)
- clientY: touch事务相对于视图(viewport)的Y轴坐标(不包含迁移转变位移)
- screenX: 相对于屏幕
- screenY: 相对于屏幕
- pageX: 相对于全部页面(包含迁移转变)
- pageY: 相对于全部页面(包含迁移转变)
- target: touch事务所产生的节点
- identifier: 一个id号,为每一个touch事务供给独一标识
对于桌面Web设计而言,在一个常规的mousemove事务中,进入节点的target属性凡是是鼠标当前悬停的属性。然则在所有的iPhone Touch事务中,target则是参照于源节点。
开辟iPhone Web App的懊恼之一就是,即使你为你的App设置好了视图区域(viewport),拖下手指时仍会让页面移动。荣幸的是,touchmove的事务对象提 供了[preventDefault()]函数(一个标准的DOM事务函数),经由过程这个办法,在你用手指拖动时,可以 让页面对峙绝对静止。
用Touch API来实现拖放
我们不必像愁闷mousemove那样费神跟踪down/up事务,因为touchmove仅在touchstart后才会触发。
node.ontouchmove = function(e){
if(e.touches.length == 1){ // 仅处理惩罚一根手指
var touch = e.touches[0]; // 获取#1号手指的信息
var node = touch.target; // 寻找拖摊开端时的节点
node.style.position = "absolute";
node.style.left = touch.pageX + "px";
node.style.top = touch.pageY + "px";
}
}
手势
这个比Touch API要轻易得多。手势(gestures)事务在两根手指任何时辰触摸屏幕时都邑触发。若是任何一根手指落在你绑定了手势处理惩罚 (gesturestart、gesturechange、gestureend)的节点上时,你都邑接管到对应的事务。
scale和rotation是这个事务对象的两个关键点。因为,用户在进行捏(pinch)或推(push)的手势时,scale可以供给给你放 大或缩小的倍数。而rotation会供给给你用户在用手指扭转时所产生的角度。
用Gestures API实现缩放和扭转
我们将应用Webkit的transform属性来扭转对象节点。
var width = 100, height = 200, rotation = ;
node.ongesturechange = function(e){
var node = e.target;
// 缩放和扭转都是相对值,
// 所以要等手势停止时再更改我们的变量
node.style.width = (width * e.scale) + "px";
node.style.height = (height * e.scale) + "px";
node.style.webkitTransform = "rotate(" + ((rotation + e.rotation) % 360) + "deg)";
}
node.ongestureend = function(e){
// 更新这些变量,以备后用
width *= e.scale;
height *= e.scale;
rotation = (rotation + e.rotation) % 360;
}
冲突
一些读者可能已经重视到,gesture只是touch事务的一种看起来更摩登的显现情势。完全正确,若是处理惩罚不当的话,你会发明一些古怪的行动。 记得在页面中记录当前所产生的信息,当它们呈现冲突时,你也许会让这些事务实现”双赢“。
步履
我把这些事务组合在一路,做了个简单的Demo:
这是一个简单的应用,显现了这些API的令人难以置信的灵活性和才能。这是一个简单的灰色方块,可以给它着色、改变边框样式,可以拖放、缩放和旋 转。
在iPhone上打开http://tinyurl.com/sp-iphone, 并测验测验以下操纵:
- 把一根手指放到有色彩的方块上,把另一根手指放在有边框的方块上
- 用两个有色彩的方块或两个有边框的方块做雷同的事
- 用一根手指在页面上拖放方块
- 缩放、扭转方块
- 一根手指拖放方块,同时另一根手指缩放扭转它;移开一根手指,另一根手指持续拖放它
我还可以做些什么?
经由过程Apple今朝供给给我们的这些API,我们能哄骗它们来实现哪些更NB的应用?我不清楚。我只知道Apple给了我们一个很沉思熟虑的 API。
这个新的API,我们可以经由过程mousedown和mouseup事务来很轻易的仿照和进修。mousemove倒是一个糟糕的东东。起首,我们只 能在手指接触后(相当于mousedown)才可以获得touch事务,而我们不管鼠标是否按下,都可以获得mousemove。此外,防止页面往返跳动 并不是我们可以主动把握的。若是给document加一个handler,用户将完全无法迁移转变页面了!
这也带给我们常规拖放体式格式的思虑。尽管拖放在鼠标键按下的景象下(touchmove的工作体式格式)只和mousemove有关系,我们仍没有任何方 法来决意拖动停止的时辰用户的手指在什么节点上(因为target参照源节点)。若是筹算应用一个拖放体系,它就必须知道已注册的拖动目标在页面上的地位 和尺寸。
注:本文译自http://www.sitepen.com/blog/2008/07/10/touching-and-gesturing-on-the-iphone/, 原作者为nroberts。