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的支持。

[转]深入了解iPad上的MouseEvent的更多相关文章

  1. 深入了解iPad上的MouseEvent【转】

    iPad上没有鼠标,所以手指在触发触摸事件(TouchEvent)的时候,系统也会产生出模拟的鼠标事件(MouseEvent).     这对于普通网页的浏览需求而言,基本可以做到与PC端浏览器无明显 ...

  2. 问题解决(一)在ipad上通过safari浏览文档

    项目背景 针对用Sencha touch 1.1开发的一个用于通过ipad浏览的网站(其实是对PC端一个网站的映射)中的一个模块的开发,这个模块的主要功能就是用户浏览各种‘报告’,这些被阅览的‘报告’ ...

  3. 通过Mac远程调试iPhone/iPad上的网页(转)

    我们知道在 Mac/PC 上的浏览器都有 Web 检查器这类的工具(如最著名的 Firebug)对前端开发进行调试,而在 iPhone/iPad 由于限于屏幕的大小和触摸屏的使用习惯,直接对网页调试非 ...

  4. iOS UIAlertController在iPhone与iPad上的区别

    很简单的一段代码: // 首先声明一个UIAlertController对象 private var alertController: UIAlertController! // 初始化UIAlert ...

  5. 把iPad上的视频推送到大麦盒子去

    把iPad上的视频推送到大麦盒子去   最近因为升级家里的宽带,服务商送了一个大麦盒子给我.   大麦盒子,就是一个网络机顶盒,用它可以通过互联网收看电视剧.电影.电视节目.音乐等等.除了它自身带的一 ...

  6. 在 iPad 上试验从用算法生成法线贴图-到法线映射光照效果

    在 iPad 上试验从用算法生成法线贴图-到法线映射光照效果 目录 概述 一般来说, 法线贴图是用高模的法线图, 低模的纹理图, 来生成较好的渲染效果. 而法线图通常是通过图像处理软件来生成的, 这里 ...

  7. iPad上的Cookie到底有多长?

    [故事背景]: 公司某个站点,特别依赖Cookie的使用,而且用的比较狠.在设计之初想当然地以为到达Cookie上限是猴年马月的事儿,没想到时过境迁,这个上限真的来了. 着手改吧,也不想投入太多.于是 ...

  8. CSS3 Media Queries在iPhone4和iPad上的运用

    CSS3 Media Queries的介绍在W3CPlus上的介绍已有好几篇文章了,但自己碰到的问题与解决的文章还是相对的较少.前几天在<修复iPhone上submit按钮bug>上介绍了 ...

  9. 在越狱的iPhone/iPad上安装自开发环境

    自开发跟自编译意思一样,后者表示一个开发语言的开发能力成熟度:前者则表示一个开发平台的开发能力成熟度. iPhone跟iPad面世这么多年,一直无法摆脱"娱乐"工具的宿命.Appl ...

随机推荐

  1. git命令评测

    近日得知git命令在库进行操作,查找git尽管小命令(当然,也不能太小),但他们是一个非常强大的组合,更重要的是,它是非常的效果不同状态的命令是不一样的打.该博文总结git命令.. Git命令 命令小 ...

  2. Qt自定义弹窗屏蔽父窗口(QWidget设置setWindowModality(Qt::ApplicationModal);以后再show)

    写Qt程序时遇到一个问题: Qt自带的弹窗功能单一,所以须要自己用ui设计弹窗的内容,这样弹窗就和普通窗口一样了,但问题是这个弹窗显示后父窗口还是活动的.网上找了很久找到了解决办法: Qt::Wind ...

  3. 深入理解最强桌面地图控件GMAP.NET --- 街景地图(StreetView)

    原文:深入理解最强桌面地图控件GMAP.NET --- 街景地图(StreetView) 很久没有更新博客了,今天无事把GMAP.NET的代码又重新翻了翻,看到了街景地图的例子. 街景地图是谷歌最早提 ...

  4. thinkphp3.2定义多模块并设置默认模块

    前台入口文件index.php <?php // +---------------------------------------------------------------------- ...

  5. C# TSF 输入法的获取

    原文 C# TSF 输入法的获取 起因: 「添雨跟打器」中存在一个问题.在 windows 8/10 里面,输入法就获取不到了.我一直没有去管这样的问题.但是也大致知道,可能是 TSF 架构的问题. ...

  6. POJ1236-Network of Schools(Tarjan + 缩点)

    主题链接 题意:给定一张有向图,问最少选择几个点能遍历全图.以及最少加入几条边使得有向图成为一个强连通图. 思路:对于有向图而言,首先求出有几个强连通分量,之后将每一个强连通分量缩点,形成DAG.本题 ...

  7. android:layout_gravity和android:gravity属性差异

    gravity的中文意思就是"重心",就是表示view横向和纵向的停靠位置 android:gravity:是对view控件本身来说的,是用来设置view本身的文本应该显示在vie ...

  8. TCP 三次握手(相当于寄信需要回执,第一次握手:我寄给你一封信。第二次握手:你回我一封信。第三次握手:我再给你一个回执,这样你才能确认我收到信了)

    TCP 连接是通过三次握手进行初始化的.三次握手的目的是同步连接双方的序列号和确认号并交换 TCP 窗口大小信息.以下步骤概述了通常情况下客户端计算机联系服务器计算机的过程: 1. 客户端向服务器发送 ...

  9. 【 D3.js 入门系列 --- 6 】 如何使移动图表

    我的个人博客是: www.ourd3js.com csdn博客为: blog.csdn.net/lzhlzz 转载请注明出处,谢谢. [5.1]节中制作了一个比較完好的图表.但它是静态的.想做出它的动 ...

  10. glibc 内存申请和释放及堆连续检查

    C语言有两种内存申请方式: 1.静态申请:当你声明全局或静态变量的时候,会用到静态申请内存.静态申请的内存有固定的空间大小.空间只在程序开始的时候申请一次,并且不再释放(除非程序结束). 2.自动申请 ...