iPad上没有鼠标,因此手指在触发触摸事件(TouchEvent)的时候,系统也会产生出模拟的鼠标事件(MouseEvent)。
这对于普通网页的浏览需求而言,基本能够作到与PC端浏览器无明显差别。可是若是你正在作一款与用户有着强交互的WebAPP程序,好比一个html5小游戏或者图片处理工具什么的,那么依赖默认模拟恐怕不能知足产品的需求。
一个一般的建议是:在iPad上(或者说各个移动终端上),你的WebAPP应该能处理好TouchEvent,而再也不依赖于MouseEvent。
然而若是你的WebAPP须要同时面向PC和iPad两种平台的浏览器用户,而迫于时间或者人力配备你无法分别提供两种版本的时候。。。你也许有必要了解一下下面这些有关iPad上MouseEvent相关的细节,而后砍掉两个平台上有明显差别的一些花哨特性,这样才能作出一个较好地兼容两个平台的WebAPP。
在阅读下文前,我假设你已经熟悉PC浏览器上MouseEvent的运做,也对TouchEvent有了粗略的了解。若是你并不了解,那理解如下各个细节可能有困难。
safari只对可点击(clickable)的HTML元素才会产生MouseEvent。这在ADC文档中也提到了。
什么叫可点击,ADC文档定义是只要HTML元素响应mousemove、mousedown、mouseup、click四种MouseEvent中的一个就算是可点击。若是你有个网页菜单只响应mouseover、mouseout,那可能不能工做,加个onclick="void(0)"就好了。但实际测试发现,只要响应任意一个MouseEvent就算可点击了,估计safari已修正此问题。
注意:下文全部关于“可点击”“不可点击”的描述都是针对是否响应MouseEvent而言,而不是指TouchEvent。
与W3C规范建议的不一样,iPad是在手指离开屏幕之后才可能会产生MouseEvent。因此像手指单击屏幕这种操做的实际事件序列一般是:touchstart->touchend->mousemove->mousedown->mouseup->click;而不是咱们指望的这样的时序:touchstart->mousedown->touchend->mouseup->click。
手指快速单击屏幕触发的MouseEvent并非紧跟在TouchEvent以后的,有一个时延。这是为了等待可能的双击操做。iPad2 Safari的实测时延大约为375ms。因此实际时序大约是这样的:(手指按下)touchstart->(手指快速提起)touchend->(等待约375ms)mousemove->mousedown->mouseup->click。
这对WebAPP的直接影响就是因为从用户操做完(手指提起)到onclick执行有375ms的延时,用户总以为你的软件反应有点慢半拍。
但若是单击速度较慢,即手指按下到提起之间的时延超过大约120ms,touchend到其余MouseEvent之间就再也不会有这个375ms的时延。由于系统认为这已经不知足手指快速双击操做的断定条件。
手指快速双击屏幕操做不会触发任何MouseEvent。我是说“任何”,就是说不光不会触发dblclick事件,连mousedown、mouseup、click等等全部MouseEvent都不会有。本操做默认的事件流是:touchstart->touchend->touchstart->touchend。若是页面开发人员不作任何限制,浏览器默认行为是尝试缩放网页。
一次手指单击操做不会同时产生mouseover和(mousedown、mouseup、click)两组事件。若是一个响应mouseover事件的元素从渲染完毕或者上一次收到mouseout以后还没有收到mouseover事件,则单击触发的事件流为:touchstart->touchend->mouseover->mousemove;反之,单击触发的事件流为:touchstart->touchend->mousemove->mousedown->mouseup->click。
不响应mouseover事件的元素只会收到上述后一种事件流,这避免绝大多数连接须要手指点击两次才能跳转页面。
一个HTML元素收到mouseover以后,只有在手指点击另外一个可点击的HTML元素时,才会收到mouseout事件。由于没有鼠标,因此不能像PC机上同样在鼠标移入移除元素区域时触发mouseover和mouseout事件,只能靠手指点击来切换mouseover;又由于不可点击的元素不会触发任何MouseEvent,因此只有在另外一个HTML元素上触发MouseEvent时前一个可点击元素才会收到mouseout事件。
手指在屏幕上移动,不会触发大量的mousemove事件。如第2点所说,只有在手指离开屏幕时,才可能产生MouseEvent消息,因此你只可能收到一次mousemove事件,包括本次操做触发的其余全部MouseEvent,坐标都是手指提起位置的坐标。因此在PC浏览器上经过mousemove实现的逻辑,在iPad上须要经过TouchEvent来实现。
实测发现,彷佛手指在屏幕上缓慢移动时,提起手指才会触发MouseEvent;若是手指快速移动,则提起手指不会触发任何MouseEvent。缘由不明。
若是一个HTML元素响应TouchEvent,手指在该元素上按下并移动,即便手指移出该元素的区域,该元素仍然会收到touchmove事件,直到手指提起收到一个touchend结束。也就是说一个HTML元素一般总能收到一个完整的touchstart->(N个)touchmove->touchend事件序列,除非系统给它发出一个touchcancel事件。这跟PC浏览器上MouseEvent特性也不太相同。
一旦在一次手指操做的事件序列touchstart->(0-N个)touchmove->touchend中的任何一个事件函数里调用了event.preventDefault(),本次操做再也不产生任何MouseEvent。因此不能指望在touchstart中调用preventDefault只阻止mousedown事件的产生。
以上各个特性在iPad2/iOS4.3.3的safari上测试验证过,对于其余safari内核的浏览器(如QQ浏览器HD等)都是适用的。
至于其余非safari内核的浏览器,在MouseEvent的支持上基本都不如safari完整和合理。例如Opera Mini只有手指单击屏幕时产生MouseEvent,而且不支持TouchEvent;UC浏览器虽然将mousedown移到了touchstart以后,可是手指移动后提起来却不能产生mouseup事件。有兴趣的能够作进一步测试。Android用户也能够在Android平板电脑上作一些测试,若是能将测试结果分享给我,我将很是感谢。 【
附录及参考文档】
1. 测试页面连接:http://hokyhu.sinaapp.com/event_test.html
你还能够在这个页面上体验iPad强大的多点触摸功能,试试看最多能检测到几个触点。
2. W3C关于TouchEvent的技术草案:https://dvcs.w3.org/hg/webevents/raw-file/tip/touchevents.html
该草案主要定义了TouchEvent相关的技术细节,并少许涉及TouchEvent与MouseEvent之间的配合。
3. ADC文档:https://developer.apple.com/library/safari/documentation/AppleApplications/Reference/SafariWebContent/SafariWebContent.pdf
文档在“Handling Events”这一章描述了对MouseEvent的支持。html