【来源地址】
http://www.cnblogs.com/pifoo/archive/2011/05/28/webkit-webapp.html
http://classjs.com/tag/%E7%A7%BB%E5%8A%A8%E7%AB%AF%E5%BC%80%E5%8F%91/
一、移动WebApp简单介绍
WebApp简介
Web app是一种通过网络(如互联网或内联网)访问的应用程序;也可以指计算机软件承载在浏览器支持环境下或使用浏览器支持语言(如JavaScript)并依赖于web 浏览器来渲染的应用程序。Web app的流行归功于网页浏览器的普及,以及使用这一轻薄客户端方便的用户体验。不必下载安装就可以实现更新和维护,具有支持跨平台的内在属性,是web app开始流行的关键原因。典型的web app产品包括web邮箱、web商店、wikis等等。
WebApp的优点
◆通过兼容性浏览器实现配置而不需要任何复杂的“转出”步骤;
◆浏览器应用程序几乎不需要客户端上的磁盘空间;
◆新功能从服务器自动传递给用户,用户自己不必升级程序;
◆可以轻松整合进入其他服务类web程序;
◆跨平台的兼容性
WebApp开发细则
对于开发者或者设计者来说,一个好处是:移动开发就技术而言,不需要再花太多的额外时间精力去学习,所有需要去做的是就设计移动网页来说,需要有全新的视觉去考虑问题。在本文中,将简单介绍在移动Web开发中需要遵守的10条原则,开发者和设计师应该遵守这些原则,这样开发出来的移动Web应用将有更好的效果。
1 安装统计分析程序
必须十分重视对访问你的移动Web应用的用户分析,这是首位的。可以通过安装各类第三方的移动Web应用统计系统达到这个目的。这样的话,可以通过查看统计程序中的各个部分获得对应的数据,比如获得访问你的移动应用的用户端的操作系统有哪些,并且可以知道用户是从哪些国家和地区访问应用。还可以通过统计程序,分析出用户是通过搜索哪些关键字从而得知你的应用的。这些数据都将给你的移动Web应用的开发带来很多帮助。
2 分析用户的组成部分
移动用户有着跟传统的通过电脑访问网站的用户有着很多不同,他们有着千奇百怪的需要。因此在开发和设计移动Web应用时,必须置身处地以用户的角度着想。如果你的应用的受众是未成年人,他们永远都是爱玩一族,因此设计移动Web应用都应该本着简单的原则,能让他们一边开车,一边购物都能很方便地操作你的应用。所以,要多分析访问你的移动Web应用的用户是由什么样的人群组成。
3 优化图片
在移动Web开发中,必须十分注意对图片的优化,否则将会给你的应用带来灾难性后果,必须考虑如下因素:
通常来说,如果尺寸大的图片加载将十分耗费时间,作为开发者和设计者,必须看清醒认识到,移动用户很多是使用低速的网络去访问你的应用的(不要老想着用户使用3g,4g网络!),所以能避免使用图片的地方应该不使用图片。
不同移动设备对图片的分辨率等的自适应是个难题,因此必须在测试阶段就要充分重视这个问题,做好测试工作。
因此,如果要在移动Web应用中使用图片,还应该采取图片压缩,CSS优化等多种措施对图片进行优化。
4 不要依赖JavaScript
不同的移动设备都有不同的浏览器,如果你开发的移动Web应用是面向绝大部分的移动设备的浏览器的话,则强烈建议不要依赖JavaScript。因为目前来说,尽管HTML 5已经开始使用,但还是不少移动浏览器对JavaScript的支持不是太好,比如Opera mini等。希望这种情况随着以后由Apple,Android和Blackberry的改进而有所改变。
5 避免使用下拉菜单
当设计移动Web应用时,一定要尽量避免使用下拉菜单。虽然在桌面电脑应用中,下拉菜单是十分常见和好用的,但在移动应用中,则需要用户不断地移动,而且容易出错。因此,如果能避免使用下拉菜单,还是应该避免过多的下拉菜单,特别是当下拉菜单内容列表过多时,加载耗费不少时间,影响性能和用户体验。
6 优化JavaScript和CSS
正如前面提到的,尽量少用JavaScript。但如果一定要使用的话,则必须使用一些优化工具去优化JavaScript和CSS,尽量压缩它们的大小,减少下载时间。现在网上已经有不少很好的工具能去实现优化JavaScript和CSS。
7 注意布局
最近,我们可能会发现,有不少移动网站都同时支持水平和垂直的布局,也就是说,在同一个移动网站中,有可能同时看到垂直布局和水平布局的界面.这对于iPhone和Android等设备来说可能比较好办,但对于其他的智能设备来说却不一定。在设计移动网站时,最好设计页面为单列的,因为这样用户就只需要在一个方向上进行移动浏览观看,而且垂直方向是符合人的一般视觉的,如果水平界面和垂直界面混合使用的话,将增加用户操作的难度。
8 充分利用手机的特性
在开发移动Web应用中,必须学习了解时下移动设备中有哪些最受人们欢迎的特性。开发者可以将这些特性融合到移动Web应用中,将会为应用增色不少。
9 提示用户到传统Web版本的网站
如果你的应用同时有移动web应用的版本和常规的web网站,那么一个很好的做法是在移动web应用中,提醒用户可以到传统的web版本的网站去获得更多的资讯。
10 提高应用的访问速度
在开发移动Web网站或应用时,最重要考虑的其中一条就是速度,你的网站或应用必须速度足够快,如果要达到这样的目的,除了前文说的尽量避免使用JavaScript和flash外,更重要的是要多关注功能和速度本身,尽量减少华而不实的东西。
--------------------------------------------
二、Web App杂谈和导读
杂谈:
导读:
--------------------------------------------
三、Web App设计杂谈
现阶段web app还很难有一个设计原则
HTML5技术仍在发展中且发展尚不完善, web app作为该技术的产物自然也是在不断试验中进步;此外,web app还要依赖兼容性浏览器更强大的渲染能力,俗话说“皮之不存毛将焉附”,在大家都期待的强大浏览器出现之前谁也难以预言web app需要做成什么样才算是一个合格的产品。在这种行业背景下,web app还难以有一个所谓的设计原则,起码现在还不构成总结一个合理设计原则的条件。
其实,所谓的设计原则本就是从已有的、典型的设计作品中倒推得出的。比如,解构主义设计风格的提出不是之前就有的,是理论家在分析总结了建筑设计师盖里、埃森曼、特斯楚米等大师的典型设计作品,结合这几位大师的设计理念后定义的一个流派名称。所谓的解构主义设计原则也是从权威大师典型作品中归纳总结的; 设计原则出现后继而可以对之后的设计起一定的指导作用。
因此本文不谈所谓的web app设计原则,现从已经上线的优秀产品中选择典型设计元素与大家讨论分享,寻找可以借鉴的地方,并借此增进对web app产品设计的认识。
Web app界面设计的8个实用技巧
Web app用户界面设计,核心是web设计;不过与一般意义上的web设计相比较,web app更加注重功能。为了在与桌面应用程序的竞争中展现其优势,web app需要提供简洁、直观、快速响应的用户界面,以便于用户在任务操作中节省精力和时间。
1.界面元素随需而变
力求简洁明了是用户界面设计的重要原则。在同一时间给用户展示的功能越多,用户需要寻找和思考的时间也就越多。同样,界面中存在的选项越少,可用功能就越明显、越容易浏览。不过简化界面并非轻而易举,尤其是你不想减少应用程序功能的情况下。
以Kontain搜索模块为例,在搜索框中有一个下拉菜单,帮助用户细化搜索范围。用户可以通过菜单选择自己想要寻找的内容。该网站通过这些选项简化了搜索框。
将高级功能隐藏起来是一种有效的简化方法。搞清楚在界面中用户最经常用的是哪些功能,然后把其他功能隐藏处理。这些可由下拉式菜单和控件完成。例如,搜索栏中的高级过滤器可以做成尾部的特殊下拉菜单样式。当用户需要这些过滤器的时候只需要几次点击就可以使用。决定哪些功能保留展示哪些需要隐藏起来,并不是一个简单的工作,需要取决于功能控件的重要程度和被使用的频繁程度。
擅长如此处理的还有CollabFinder, 如上图。用户点击搜索链接后并没有被马上带到其他页面;搜索框控件下拉下来,允许用户在当前页面内直接进行搜索操作。这样的设计方式,既保持了用户视觉焦点的稳定,又使得整个页面在不使用某个特定功能的情况下简洁清爽。
2.为模态窗口增加边缘阴影
弹出式菜单和窗口周边的阴影不仅仅是为了视觉美观。阴影一方面增大了菜单或窗口的尺寸,有助于将菜单或窗口从背景中区别开来;另一方面通过灰度化的边缘阴影可以屏蔽背景内容的噪音干扰。
这个技巧根植于传统桌面程序,帮助用户将注意力集中在弹出的窗口。由于很多模态窗口不容易从桌面程序内容页面中凸显出来,阴影可以使它们看起来具有立体效果、仿佛悬浮于其他内容之上,于是拉近了模态窗口与用户的距离。
如上图,Digg的登录窗口边缘拥有厚厚的阴影,对下面内容的视觉噪音起到了有效的屏蔽作用。
为实现这样的效果,设计师往往将透明的PNG背景图片作为容器,再把内容填充到容器中,同时等距离填充弹出框各边缘。或者使用具有透明边框的背景图片,并将内容框绝对定位在其中。另外,也可以使用基于JavaScript的lightboxes命令或者CSS3中的 drop shadows命令,但需要注意浏览器是否支持。
3.空白状态时告诉用户可以做什么
当设计web app的时候,不仅需要关心一般情况下的信息展示,还要确保界面在空白状态时表现良好、具有指引作用。页面中还没有产生任何信息的时候,可以在空白区域放置一条帮助信息告诉用户如何开始。例如,一个项目管理的应用程序主页会列出用户的项目,假如还没有什么项目信息,可以为用户提供一个项目创建页面的链接。即使这个页面上已经存在了这样一个功能按钮,一个额外的帮助并不会有什么妨碍。
如上图,Campaign Monitor在右边方向提供了一个建立新信息的快速入口。
Wufoo的表单页面有醒目的、友好的信息鼓励用户去创建新的表单。
这个技巧可以有效地鼓励用户试用该服务,并在注册后立即进行使用。通过应用程序的单一操作步骤可以帮助用户理解这个应用的优势以及对他们是否有用。
此外,只为用户展示最重要的功能选项也很关键。一股脑的将众多功能倾泻给用户并没有什么实际意义。需要牢记的是,用户通常想从应用中获得或多或少的信息,但却不想跳进细节中,用户没有时间也没有兴趣。
在空白状态中激励用户,可以显著地降低用户的流失率,并帮助潜在的用户更好的理解程序系统是如何工作的。
4.Button状态积极反馈
许多web app拥有自定义样式的按钮。默认的输入按钮可能不适合某些情景,文字链接有时候看起来又太含蓄。需要注意的是,把链接做成Button样式的时候,它们就应该有button的表现形式。比如,在点击button的时候它们应该会出现被“压”过的样子。这不仅仅是纯粹的视觉变化。及时反馈给用户,可以使web app感觉起来更灵敏,与桌面应用程序的用户体验更接近。
可以使用CSS添加按钮的“pressed”等状态,实现在不同状态下显示不同背景图片的功能。
例如Highrise中的按钮,在鼠标指针点击的时候会呈现 “pressed”状态效果,为用户提供了灵敏的反馈感受。
5.使用上下文情境导航
在既定的情境下考虑用户希望看什么、需要什么是非常重要的。不需要在每一个地方都放置相同的导航控件,因为用户不是在任何情况下都需要它们。
上下文情境导航最好的一个例子就是Office 2007中,原先默认的工具栏集合被换成了带状控件形式。每一项tab控制着一组相关联的功能,如编辑图形、校对或者简单书写。
Web app可以从这种上下文情境导航中获益,仅展示用户需要的、而不是所有可用的功能,从而保持用户界面的整洁清爽。
例如上图中,Lighthouse 有非常典型的tab导航菜单;然而,在tab导航栏的下方它还有二级导航,在这个二级导航中只显示网站活跃部分的相关条目。
6.更加重视关键功能
并不是所有的控件都拥有相同的重要性。例如创建一个新的条目,页面中会有“创建”“取消”两个button. 这里的“创建”就要更加重要些,因为这是大多数情况下用户即将要做的事情。极少的情况下用户才会去点击取消。虽然这两个控件并排放置,但是不要给予相同的重视程度。
为了将注意力引导到“创建”上,我们可以尝试使用不用的风格或样式。一种方式是将“创建”设计成button样式,“取消”设计成文字链接样式。另一种方式是在视觉上使用使用不同的颜色,并使button略有凸起的效果。这样便于抓住用户的目光。
例如在Google+创建新圈子的弹窗中,创建按钮在视觉上具备了更加醒目的效果,拥有该页面中更高的重视等级。
7.嵌入视频
虽然图片和文字是向用户介绍应用程序功能的很好的方式,但如果资源允许的话,视频将是一个更优方案。近年来视频在网络上的使用越来越频繁。Web app的截屏视频经常被使用在营销网站中来展示产品的功能;然而这并不是视频使用的唯一方式。
GoodBarry 在其首页中使用截屏视频来展示产品。同时它还在应用中嵌入了视频来指导用户如何去开始。
MailChimp在管理面板中使用教程视频以帮助新用户。
一些web app使用内部嵌入的视频帮助用户了解产品的特定功能。视频是快速演示产品如何使用的绝佳方法,因为与文字相比视频更容易被用户所接受,而且视频可以使用户准确地看到需要做什么,更加清晰。
8.让升级或降级的提示简洁、不扰民
在很多互联网产品中都会有不同权限的用户账户存在,比如邮箱、空间、网盘存储、SNS产品等。在用户拥有了一个账户后,他们可以对账户进行升级或降级。如何设计界面来提示用户他们可以升级而不去干扰用户的工作流程呢?设计师肯定不愿意在应用程序之外完成这件事情,这样的提示应该是和app是无缝连接的,而且最好是让用户感觉方便。因此升级账户的提示最好放在app内完成。
通过几个例子我们了解一下升级账户的处理方式。
FreshBooks 的升级提示是一直存在的,被放置在了web app的底部。如上图。由于提示是在界面的工作区以外的位置,并不会对用户的工作流程造成影响。
在Basecamp的升级提示中,用户可以很清晰地得知升级后将会有哪些变化。请看上图。
在CompVersions中,各种升级后的变化情况很直观 ,整个页面简洁清晰。请见上图。
--------------------------------------------
四、webkit webApp的开发技巧
1. viewport:
也就是可视区域。对于桌面浏览器,我们都很清楚viewport是什么,就是出去了所有工具栏、状态栏、滚动条等等之后用于看网页的区域,
这是真正有效的区域。由于移动设备屏幕宽度不同于传统web,因此我们需要改变viewport;
实际上我们可以操作的属性有4 个:
width - // viewport 的宽度 (范围从200 到10,000,默认为980 像素) height - // viewport 的高度 (范围从223 到10,000)
initial-scale - // 初始的缩放比例 (范围从>0 到10)
minimum-scale - // 允许用户缩放到的最小比例 maximum-scale - // 允许用户缩放到的最大比例
user-scalable - // 用户是否可以手动缩 (no,yes) |
那么到底这些设置如何让Safari 知道?其实很简单,就一个meta,形如:
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> //编码 <meta id="viewport" name="viewport" content="width=320; initial-scale=1.0;maximum-scale=1.0; user-scalable=no;"/> <meta name=”apple-mobile-web-app-capable” content=”yes” /> // 离线应用的另一个技巧 <meta name=”apple-mobile-web-app-status-bar-style” content=black” /> // 隐藏状态栏 <meta content="black" name="apple-mobile-web-app-status-bar-style" />//指定的iphone中safari顶端的状态条的样式 <meta content="telephone=no" name="format-detection" /> //告诉设备忽略将页面中的数字识别为电话号码 <meta name="Author" contect="Mr.He"/ > |
在设置了initial-scale=1 之后,我们终于可以以1:1 的比例进行页面设计了。关于viewport,还有一个很重要的概念是:iphone 的safari 浏览器完全没有滚动条,而且不是简单的“隐藏滚动条”,是根本没有这个功能。iphone 的safari 浏览器实际上从一开始就完整显示了这个网页,然后用viewport 查看其中的一部分。当你用手指拖动时,其实拖的不是页面,而是viewport。浏览器行为的改变不止是滚动条,交互事件也跟普通桌面不一样。
2. link-横屏和竖屏样式设置:
<link rel=”apple-touch-startup-image” href=”startup.png” />// 设置开始页面图片 <link rel=”apple-touch-icon” href=”iphon_tetris_icon.png”/>// 在设置书签的时候可以显示好看的图标 <link rel="stylesheet" media="all and (orientation:portrait)" href="portrait.css"> // 肖像模式样式 <link rel="stylesheet" media="all and (orientation:landscape)" href="landscape.css" // 风景模式样式
//竖屏时使用的样式 <style media="all and (orientation:portrait)" type="text/css"> #landscape { display: none; } </style>
//横屏时使用的样式 <style media="all and (orientation:landscape)" type="text/css"> #portrait { display: none; } </style> |
3. 事件 :
// 手势事件 touchstart //当手指接触屏幕时触发 touchmove //当已经接触屏幕的手指开始移动后触发 touchend //当手指离开屏幕时触发 touchcancel
// 触摸事件 gesturestart //当两个手指接触屏幕时触发 gesturechange //当两个手指接触屏幕后开始移动时触发 gestureend
// 屏幕旋转事件 onorientationchange
// 检测触摸屏幕的手指何时改变方向 orientationchange
// touch事件支持的相关属性 touches targetTouches changedTouches clientX // X coordinate of touch relative to the viewport (excludes scroll offset) clientY // Y coordinate of touch relative to the viewport (excludes scroll offset) screenX // Relative to the screen screenY // Relative to the screen pageX // Relative to the full page (includes scrolling) pageY // Relative to the full page (includes scrolling) target // Node the touch event originated from identifier // An identifying number, unique to each touch event |
4. JS检测屏幕旋转事件:onorientationchange
添加屏幕旋转事件侦听,可随时发现屏幕旋转状态(左旋、右旋还是没旋)。例子:
// 判断屏幕是否旋转 function orientationChange() { switch(window.orientation) { case 0: alert("肖像模式 0,screen-width: " + screen.width +"; screen-height:" + screen.height); break; case -90: alert("左旋 -90,screen-width: " + screen.width +"; screen-height:" + screen.height); break; case 90: alert("右旋 90,screen-width: " + screen.width +"; screen-height:" + screen.height); break; case 180: alert("风景模式 180,screen-width: " + screen.width +"; screen-height:" + screen.height); break; };<br>}; // 添加事件监听 addEventListener('load',function(){ orientationChange(); window.onorientationchange = orientationChange; }); |
5. 隐藏地址栏 & 处理事件的时候,防止滚动条出现:
// 隐藏地址栏 & 处理事件的时候 ,防止滚动条出现 addEventListener('load',function(){ setTimeout(function(){ window.scrollTo(0, 1); }, 100); }); |
6. 双手指滑动事件:
// 双手指滑动事件 addEventListener('load', function(){ window.onmousewheel = twoFingerScroll;}, false // 兼容各浏览器,表示在冒泡阶段调用事件处理程序 (true 捕获阶段) ); function twoFingerScroll(ev) { var delta =ev.wheelDelta/120; //对 delta 值进行判断(比如正负) ,而后执行相应操作 return true; }; |
7. 判断是否为iPhone:
// 判断是否为 iPhone : function isAppleMobile() { return (navigator.platform.indexOf('iPad') != -1); }; |
8. localStorage:
例子 :(注意数据名称 n 要用引号引起来)
var v = localStorage.getItem('n') ? localStorage.getItem('n') :""; // 如果名称是 n 的数据存在 ,则将其读出 ,赋予变量 v 。 localStorage.setItem('n', v); // 写入名称为 n、值为 v 的数据 localStorage.removeItem('n'); // 删除名称为 n 的数据 |
9. 使用特殊链接(如直接拨号和发短信):
如果你关闭自动识别后 ,又希望某些电话号码能够链接到 iPhone 的拨号功能 ,那么可以通过这样来声明电话链接 ,
<a href="tel:12345654321">打电话给我</a> <a href="sms:12345654321">发短信</a> 或用于单元格: <td onclick="location.href='tel:122'"> |
10. 自动大写与自动修正
要关闭这两项功能,可以通过autocapitalize 与autocorrect 这两个选项:
<input type="text" autocapitalize="off" autocorrect="off" /> |
11. WebKit CSS:
①“盒模型”的具体描述性质的包围盒块内容,包括边界,填充等等。
-webkit-border-bottom-left-radius: radius; -webkit-border-top-left-radius: horizontal_radius vertical_radius; -webkit-border-radius: radius; //容器圆角 -webkit-box-sizing: sizing_model; 边框常量值:border-box/content-box -webkit-box-shadow: hoff voff blur color; //容器阴影(参数分别为:水平X 方向偏移量;垂直Y 方向偏移量;高斯模糊半径值;阴影颜色值) -webkit-margin-bottom-collapse: collapse_behavior; 常量值:collapse/discard/separate -webkit-margin-start: width; -webkit-padding-start: width; -webkit-border-image: url(borderimg.gif) 25 25 25 25 round/stretch round/stretch; -webkit-appearance: push-button; //内置的CSS 表现,暂时只支持push-button |
②“视觉格式化模型”描述性质,确定了位置和大小的块元素。
direction: rtl unicode-bidi: bidi-override; 常量:bidi-override/embed/normal |
③“视觉效果”描述属性,调整的视觉效果块内容,包括溢出行为,调整行为,能见度,动画,变换,和过渡。
clip: rect(10px, 5px, 10px, 5px) resize: auto; 常量:auto/both/horizontal/none/vertical visibility: visible; 常量: collapse/hidden/visible -webkit-transition: opacity 1s linear; 动画效果 ease/linear/ease-in/ease-out/ease-in-out -webkit-backface-visibility: visibler; 常量:visible(默认值)/hidden -webkit-box-reflect: right 1px; 镜向反转 -webkit-box-reflect: below 4px -webkit-gradient(linear, left top, left bottom, from(transparent), color-stop(0.5, transparent), to(white)); -webkit-mask-image: -webkit-gradient(linear, left top, left bottom, from(rgba(0,0,0,1)), to(rgba(0,0,0,0)));; //CSS 遮罩/蒙板效果 -webkit-mask-attachment: fixed; 常量:fixed/scroll -webkit-perspective: value; 常量:none(默认) -webkit-perspective-origin: left top; -webkit-transform: rotate(5deg); -webkit-transform-style: preserve-3d; 常量:flat/preserve-3d; (2D 与3D) |
④“生成的内容,自动编号,并列出”描述属性,允许您更改内容的一个组成部分,创建自动编号的章节和标题,和操纵的风格清单的内容。
content: “Item” counter(section) ” “; This resets the counter. First section >two section three section counter-increment: section 1; counter-reset: section; |
⑤“分页媒体”描述性能与外观的属性,控制印刷版本的网页,如分页符的行为。
page-break-after: auto; 常量:always/auto/avoid/left/right page-break-before: auto; 常量:always/auto/avoid/left/right page-break-inside: auto; 常量:auto/avoid |
⑥“颜色和背景”描述属性控制背景下的块级元素和颜色的文本内容的组成部分。
-webkit-background-clip: content; 常量:border/content/padding/text -webkit-background-origin: padding; 常量:border/content/padding/text -webkit-background-size: 55px; 常量:length/length_x/length_y |
⑦ “字型”的具体描述性质的文字字体的选择范围内的一个因素。报告还描述属性用于下载字体定义。
unicode-range: U+00-FF, U+980-9FF; |
⑧“文本”描述属性的特定文字样式,间距和自动滚屏。
text-shadow: #00FFFC 10px 10px 5px; text-transform: capitalize; 常量:capitalize/lowercase/none/uppercase word-wrap: break-word; 常量:break-word/normal -webkit-marquee: right large infinite normal 10s; 常量:direction(方向) increment(迭代次数) repetition(重复) style(样式) speed(速度); -webkit-marquee-direction: ahead/auto/backwards/down/forwards/left/reverse/right/up -webkit-marquee-incrementt: 1-n/infinite(无穷次) -webkit-marquee-speed: fast/normal/slow -webkit-marquee-style: alternate/none/scroll/slide -webkit-text-fill-color: #ff6600; 常量:capitalize, lowercase, none, uppercase -webkit-text-security: circle; 常量:circle/disc/none/square -webkit-text-size-adjust: none; 常量:auto/none; -webkit-text-stroke: 15px #fff; -webkit-line-break: after-white-space; 常量:normal/after-white-space -webkit-appearance: caps-lock-indicator; -webkit-nbsp-mode: space; 常量: normal/space -webkit-rtl-ordering: logical; 常量:visual/logical -webkit-user-drag: element; 常量:element/auto/none -webkit-user-modify: read- only; 常量:read-write-plaintext-only/read-write/read-only -webkit-user-select: text; 常量:text/auto/none |
⑨“表格”描述的布局和设计性能表的具体内容。
-webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px; -webkit-column-break-after: right; 常量:always/auto/avoid/left/right -webkit-column-break-before: right; 常量:always/auto/avoid/left/right –webkit-column-break-inside: logical; 常量:avoid/auto -webkit-column-count: 3; //分栏 -webkit-column-rule: 1px solid #fff; style:dashed,dotted,double,groove,hidden,inset,none,outset,ridge,solid |
⑩“用户界面”描述属性,涉及到用户界面元素在浏览器中,如滚动文字区,滚动条,等等。报告还描述属性,范围以外的网页内容,如光标的标注样式和显示当您按住触摸触摸
目标,如在iPhone上的链接。
-webkit-box-align:baseline,center,end,start,stretch 常量:baseline/center/end/start/stretch -webkit-box-direction:normal;常量:normal/reverse -webkit-box-flex: flex_valuet -webkit-box-flex-group: group_number -webkit-box-lines: multiple; 常量:multiple/single -webkit-box-ordinal-group: group_number -webkit-box-orient: block-axis; 常量:block-axis/horizontal/inline-axis/vertical/orientation –webkit-box-pack: alignment; 常量:center/end/justify/start |
12. 动画过渡
这是 Webkit 中最具创新力的特性:使用过渡函数定义动画。
-webkit-animation: title infinite ease-in-out3s; animation 有这几个属性: -webkit-animation-name: //属性名,就是我们定义的keyframes -webkit-animation-duration:3s //持续时间 -webkit-animation-timing-function: //过渡类型:ease/ linear(线性) /ease-in(慢到快)/ease-out(快到慢) /ease-in-out(慢到快再到慢) /cubic-bezier -webkit-animation-delay:10ms //动画延迟(默认0) -webkit-animation-iteration-count: //循环次数(默认1),infinite 为无限 -webkit-animation-direction: //动画方式:normal(默认 正向播放); alternate(交替方向,第偶数次正向播放,第奇数次反向播放) |
这些同样是可以简写的。但真正让我觉的很爽的是keyframes,它能定义一个动画的转变过程供调用,过程为0%到100%或from(0%)到to(100%)。简单点说,只要你有想法,你想让元素在这个过程中以什么样的方式改变都是很简单的。
-webkit-transform: 类型(缩放scale/旋转rotate/倾斜skew/位移translate) scale(num,num) 放大倍率。scaleX 和 scaleY(3),可以简写为:scale(* , *) rotate(*deg) 转动角度。rotateX 和 rotateY,可以简写为:rotate(* , *) Skew(*deg) 倾斜角度。skewX 和skewY,可简写为:skew(* , *) translate(*,*) 坐标移动。translateX 和translateY,可简写为:translate(* , *)。 |
实现模拟弹出消息框(Alert)的例子:
①定义过渡(在<style type="text/css">段中描述keyframes):
@-webkit-keyframes DivZoom { 0% { -webkit-transform: scale(0.01) } 60% { -webkit-transform: scale(1.05) } 80% { -webkit-transform: scale(0.95) } 100% { -webkit-transform: scale(1.00) } } .sZoom { -webkit-animation: DivZoom0.5s ease-in-out } |
(很容易看懂,将元素从缩小的0.01 倍--很小但不能为0 倍,放大到1.05 倍,再缩小到0.95倍,最后到1 倍即正常大小。整个过渡过程事件为0.5 秒,动画方式为ease-in-out,即慢到快再到慢,默认只进行1 次过渡。这正是大家经常看到的 iPhone 弹出的提示信息的动画效果!)
②定义元素(在<body>段中):
<div id="layerH" style="-webkit-border-radius:12px; border:2px solid #FFF;-webkit-box-shadow: 0px 2px 4px #888;position: absolute; left: 24px; top: 106px;<br>width: 256px; height: 268px; padding-left: 8px; padding-right: 8px;color: #FFFFFF; text-shadow: 1px 1px 1px #000; text-align: center;background-color: RGBA(32,48,96,0.9); background-image:url('BG-Msg.png'); background-repeat:no-repeat; z-index: 1; visibility: hidden; "> <p><span style="font-size: 16pt; font-weight: bold">使用说明</span></p> <hr noshadesize="1"> <div id="HelpText" style="height: 120px">说明文字</div> <hr noshadesize="1"> <form name="formV" method="POST"> <input type="button" value="确认" name="B1" style="width: 100%; height: 40px; font-size: 14pt; ont-weight: bold; color: #FFFFFF; text-shadow: 0px -1px 1px #000;" onclick=" layerH.style.visibility='hidden'"> </form> </div> |
③启动动画(在 javascript 定义的函数中)
function pHelp() { layerH.style.visibility ='visible' layerH.style.cssText ="-webkit-animation-delay: " + Math.random() +"ms" layerH.className ='sZoom' } |
(这个启动函数就很好理解了。但是为什么要使用-webkit-animation-delay 这句呢?因为当一个元素过渡显示完成后,若其样式没有变化,下一次将无法进行过渡动画显示。我们巧妙的利用其动画延迟时间定义,使其有所变化,就避免了上述问题。其中使用随机数函数Math.random(),产生一个大于0 小于1 的随机数。当然,延迟零点几毫秒,用户是不会察觉的。)
13. 创建桌面图标和启动画面
官方文档参考: 苹果ios 系统从4.2开始就支持apple-touch-icon属性,在meta标签中指定它的值可以使得你的网页在保存至主屏时,显示为自定义的icon,而不是网页的缩略图。
<link rel="apple-touch-icon" href="/custom_icon.png"/>
<link rel="apple-touch-icon" href="touch-icon-iphone.png" />
<link rel="apple-touch-icon" sizes="72x72" href="touch-icon-ipad.png" />
<link rel="apple-touch-icon" sizes="114x114" href="touch-icon-iphone4.png" />
苹果提供了sizes这个属性,为了方便适应多设备。而如果你不指定这个属性,默认size 会是57 * 57大小。另外对应 apple-touch-icon 苹果还有另外一个属性 apple-touch-icon-precomposed 他们的不同之处就是,但使用 apple-touch-icon-precomposed 属性的时候,苹果不会给桌面图标加一个高光效果。
苹果系统3.0以后就支持 Startup Image 属性,webapp 在苹果手机上可以给网页声明StartUp Image ,使得当webapp 从主屏打开时,会有一张封面图片,很类似原生app。但是被声明的图片对于iphone和itouch 大小只能是 320 x 460 ,其他大小的都无效。但是同样你可以通过sizes 来进行多设备适配。
<link rel="apple-touch-startup-image" href="/startup.png">
//for iphone Retina Display high
<link rel="apple-touch-startup-image" sizes="640x960" href="img/splash-screen-640x960.png" />
//for iPad Landscape
<link rel="apple-touch-startup-image" sizes="1024x748" href="img/splash-screen-1024x748.png" />
//for iPad Portrait
<link rel="apple-touch-startup-image" sizes="768x1004" href="img/splash-screen-768x1004.png" />
14. 去除链接的点击阴影
html,body{-webkit-tap-highlight-color:rgba(0,0,0,0)}
15. 尽量弃用click
在手机上绑定click 事件,会使得操作有300ms 的延迟,体验并不是很好。在用js绑定click的时候尽量用tap事件代替,可以采用第三方的触摸库来解决。
16. css尽量少用position的绝对和相对定位
对于渲染,过多绝对定位或是相对定位的元素,会使得你的浏览器不堪重负而崩溃。这点在mobile safari 上体现的很明显。所以也尽量少使用绝对定位来完成布局
17. css3动画闪烁问题
关于使用css3动画的时尽量利用3D加速,从而使得动画变得流畅。动画过程中的动画闪白可以通过backface-visibility 隐藏。
-webkit-transform-style: preserve-3d;
-webkit-backface-visibility: hidden;
18. 如何检测用户是否从主屏启动webapp
iOS中浏览器直接访问站点时,navigator.standalone属性为false,从主屏启动webapp时,navigator.standalone属性为true。
19. 关闭键盘大小写
移动版本webkit为input元素提供了autocapitalize属性,通过指定autocapitalize=”off”来关闭键盘默认首字母大写。
20. 获取滚动条的值
在android中可以通过正常的document.documentElement.scrollTop和scrollLeft获取到滚动条的值,但是在ios中没有滚动条的概念,如果非要获取则使用window.scrollY和scrollX。
21. 动画方式隐藏头部地址栏
在Android和ios下都起作用
document.addEventListener('DOMContentLoaded', function() {
setTimeout(function(){window.scrollTo(0, 1);}, 100);
}, false);
22.处理设备的横竖屏
为了应对移动设备屏幕的碎片化,我们在开发Mobile Web应用时,一个最佳实践就是采用流式布局,保证最大可能地利用有限的屏幕空间。由于屏幕存在着方向性,用户在切换了屏幕的方向后,有些设计上或实现上的问题就会凸显——我们至少需要处理一下当前显示元素的宽度的适配(当然,要做的可能不仅仅是这个)。很多时候,我们需要为不同的屏幕方向来设计对应的应用显示模式,这个时候,实时地获知设备的模竖屏状态就显得极为重要。
window.orientation属性与onorientationchange事件
window.orientation :这个属性给出了当前设备的屏幕方向,0表示竖屏,正负90表示横屏(向左与向右)模式
onorientationchange : 在每次屏幕方向在横竖屏间切换后,就会触发这个window事件,用法与传统的事件类似
1:使用onorientationchange事件的回调函数,来动态地为body标签添加一个叫orient的属性,同时以body[orient=landspace]或body[orient=portrait]的方式在css中定义对应的样式,这样就可以实现在不同的屏幕模式下显示不同的样式。如下代码示例:
Html代码
<!Doctype html>
<html>
<head>
<meta charset="utf-8">
<meta id="viewport" name="viewport" content="width=device-width,initial-scale=1.0;">
<title>横竖屏切换检测</title>
<style type="text/css">
body[orient=landscape]{
background-color: #ff0000;
}
body[orient=portrait]{
background-color: #00ffff;
}
</style>
</head>
<body orient="landspace">
<div>
内容
</div>
<script type="text/javascript">
(function(){
if(window.orient==0){
document.body.setAttribute("orient","portrait");
}else{
document.body.setAttribute("orient","landscape");
}
})();
window.onorientationchange=function(){
var body=document.body;
var viewport=document.getElementById("viewport");
if(body.getAttribute("orient")=="landscape"){
body.setAttribute("orient","portrait");
}else{
body.setAttribute("orient","landscape");
}
};
</script>
</body>
</html>
类似的思路,不通过CSS的属性选择器来实现,如下代码的实现方案:
Html代码
<!Doctype html>
<html>
<head>
<meta charset="utf-8">
<meta id="viewport" name="viewport" content="width=device-width,initial-scale=1.0;">
<title>横竖屏切换检测</title>
<style type="text/css">
.landscape body {
background-color: #ff0000;
}
.portrait body {
background-color: #00ffff;
}
</style>
</head>
<body orient="landspace">
<div>
内容
</div>
<script type="text/javascript">
(function(){
var init=function(){
var updateOrientation=function(){
var orientation=window.orientation;
switch(orientation){
case 90:
case -90:
orientation="landscape";
break;
default:
orientation="portrait";
break;
}
document.body.parentNode.setAttribute("class",orientation);
};
window.addEventListener("orientationchange",updateOrientation,false);
updateOrientation();
};
window.addEventListener("DOMContentLoaded",init,false);
})();
</script>
</body>
</html>
使用media query方式
这是一种更为方便的方式,使用纯CSS就实现了对应的功能,如下代码演示:
Html代码
<!Doctype html>
<html>
<head>
<meta charset="utf-8">
<meta id="viewport" name="viewport" content="width=device-width,initial-scale=1.0;">
<title>横竖屏切换检测</title>
<style type="text/css">
@media all and (orientation : landscape) {
body {
background-color: #ff0000;
}
}
@media all and (orientation : portrait){
body {
background-color: #00ff00;
}
}
</style>
</head>
<body>
<div>
内容
</div>
</body>
</html>
低版本浏览器的平稳降级
如果目标移动浏览器不支持media query,同时window.orientation也不存在,则我们需要采用另外一种方式来实现————使用定时器“伪实时”地对比当前窗口的高(window.innerHeight)与宽(window.innerWidth)之比,从而判定当前的横竖屏状态。如下代码所示:
Html代码
<!Doctype html>
<html>
<head>
<meta charset="utf-8">
<meta id="viewport" name="viewport" content="width=device-width,initial-scale=1.0;">
<title>按键</title>
<style type="text/css">
.landscape body {
background-color: #ff0000;
}
.portrait body {
background-color: #00ffff;
}
</style>
<script type="text/javascript">
(function(){
var updateOrientation=function(){
var orientation=(window.innerWidth > window.innerHeight)? "landscape" : "portrait";
document.body.parentNode.setAttribute("class",orientation);
};
var init=function(){
updateOrientation();
window.setInterval(updateOrientation,5000);
};
window.addEventListener("DOMContentLoaded",init,false);
})();
</script>
</head>
<body>
<div>
内容
</div>
</body>
</html>
统一解决方案
将以上的两种解决方案整合在一起,就可以实现一个跨浏览器的解决方案,如下代码:
Html代码
<!Doctype html>
<html>
<head>
<meta charset="utf-8">
<meta id="viewport" name="viewport" content="width=device-width,initial-scale=1.0;">
<title>横竖屏切换检测</title>
<style type="text/css">
.landscape body {
background-color: #ff0000;
}
.portrait body {
background-color: #00ffff;
}
</style>
<script type="text/javascript">
(function(){
var supportOrientation=(typeof window.orientation == "number" && typeof window.onorientationchange == "object");
var updateOrientation=function(){
if(supportOrientation){
updateOrientation=function(){
var orientation=window.orientation;
switch(orientation){
case 90:
case -90:
orientation="landscape";
break;
default:
orientation="portrait";
}
document.body.parentNode.setAttribute("class",orientation);
};
}else{
updateOrientation=function(){
var orientation=(window.innerWidth > window.innerHeight)? "landscape":"portrait";
document.body.parentNode.setAttribute("class",orientation);
};
}
updateOrientation();
};
var init=function(){
updateOrientation();
if(supportOrientation){
window.addEventListener("orientationchange",updateOrientation,false);
}else{
window.setInterval(updateOrientation,5000);
}
};
window.addEventListener("DOMContentLoaded",init,false);
})();
</script>
</head>
<body>
<div>
内容
</div>
</body>
</html>
【原文】http://davidbcalhoun.com/2010/dealing-with-device-orientation
--------------------------------------------
补充:
1. 锁定 viewport
ontouchmove="event.preventDefault()" //锁定viewport,任何屏幕操作不移动用户界面(弹出键盘除外)。 |
2. 被点击元素的外观变化,可以使用样式来设定:
-webkit-tap-highlight-color: 颜色 |
3. 侦测iPhone/iPod
开发特定设备的移动网站,首先要做的就是设备侦测了。下面是使用Javascript侦测iPhone/iPod的UA,然后转向到专属的URL。
if((navigator.userAgent.match(/iPhone/i)) || (navigator.userAgent.match(/iPod/i))) { if (document.cookie.indexOf("iphone_redirect=false") == -1) { window.location =" http://m.example.com "; } } |
虽然Javascript是可以在水果设备上运行的,但是用户还是可以禁用。它也会造成客户端刷新和额外的数据传输,所以下面是服务器端侦测和转向:
if(strstr($_SERVER['HTTP_USER_AGENT'],'iPhone') || strstr($_SERVER['HTTP_USER_AGENT'],'iPod')) { header('Location: http://yoursite.com/iphone '); exit(); } |
4. 阻止旋转屏幕时自动调整字体大小
html, body, form, fieldset, p, div, h1, h2, h3, h4, h5, h6 {-webkit-text-size-adjust:none;} |
5. iPhone才识别的CSS
如果不想设备侦测,可以用CSS媒体查询来专为iPhone/iPod定义样式。
@media screen and (max-device-width: 480px) {} |
6. 缩小图片
网站的大图通常宽度都超过480像素,如果用前面的代码限制了缩放,这些图片在iPhone版显示显然会超过屏幕。好在iPhone机能还够,我们可以用CSS让iPhone自动将大图片缩小显示。
@mediascreen and (max-device-width:480px){ img{max-width:100%;height:auto;} } |
7. 模拟:hover伪类
因为iPhone并没有鼠标指针,所以没有hover事件。那么CSS :hover伪类就没用了。但是iPhone有Touch事件,onTouchStart 类似 onMouseOver,onTouchEnd 类似 onMouseOut。所以我们可以用它来模拟hover。使用Javascript:
var myLinks = document.getElementsByTagName('a'); for(var i = 0; i < myLinks.length; i++){ myLinks[i].addEventListener(’touchstart’,function(){this.className = “hover”;},false); myLinks[i].addEventListener(’touchend’,function(){this.className = “”;},false); } |
然后用CSS增加hover效果:
a:hover, a.hover {/* 你的hover效果 */ } |
这样设计一个链接,感觉可以更像按钮。并且,这个模拟可以用在任何元素上。
8、多指触控的问题
多根手指在屏幕上,提起一根,会刷新一次全局 touch!重新触发第一根手指的touchstart,这点和苹果官方网站上介绍的不同。
9、device-pixel-ratio(详细见:http://www.zhangxinxu.com/wordpress/?p=2568)
它得意思是:Gives the number of device pixels per CSS pixel.也即我们抒写得css px和物理px(device px)之间得比率。
iphone的物理分辨率是320X480,但是呈现的内容却是640x960,但其实我们设置的css px是相对于物理分辨率的,即320x480,但是因为我们设置的css px要显示在更宽阔的640x960的内容区域里头,所以10个css px在640x960的呈现效果就相当于5个device px在320x480的呈现效果。所以每个css px。
css px与device px
所以如果图片得大小是100x100,那么到iphone里头就会被放大2倍,于是图像会变得比以前模糊,通常得解决办法是,用background-size设置为50%,以前的一半,然后再放iphone放大2倍,等于没变化,恢复到正常效果,不模糊了。
devicePixelRatio
window.devicePixelRatio is the ratio between physical pixels and device-independent pixels (dips) on the device.
window.devicePixelRatio = physical pixels / dips
10、Viewport详解
什么是Viewport
手机浏览器是把页面放在一个虚拟的“窗口”(viewport)中,通常这个虚拟的“窗口”(viewport)比屏幕宽,这样就不用把每个网页挤到很小的窗口中(这样会破坏没有针对手机浏览器优化的网页的布局),用户可以通过平移和缩放来看网页的不同部分。移动版的 Safari 浏览器最新引进了 viewport 这个 meta tag,让网页开发者来控制 viewport 的大小和缩放,其他手机浏览器也基本支持。
Viewport 基础
一个常用的针对移动网页优化过的页面的 viewport meta 标签大致如下:
<meta name=”viewport” content=”width=device-width, initial-scale=1, maximum-scale=1″>
width:控制 viewport 的大小,可以指定的一个值,如果 600,或者特殊的值,如 device-width 为设备的宽度(单位为缩放为 100% 时的 CSS 的像素)。
height:和 width 相对应,指定高度。
initial-scale:初始缩放比例,也即是当页面第一次 load 的时候缩放比例。
maximum-scale:允许用户缩放到的最大比例。
minimum-scale:允许用户缩放到的最小比例。
user-scalable:用户是否可以手动缩放
关于viewport的一些问题
viewport并非只是ios上的独有属性,在android、winphone上同样也有viewport。它们要解决的问题是相同的,即无视设备的真实分辨率,直接通过dpi,在物理尺寸和浏览器之间重设分辨率,这个分辨率和设备的分辨率无关。比如,你拿个3.5寸-320 * 480的iphone3 gs、3.5寸-640 * 960的iphone4或者9.7寸-1024*768的ipad2,虽然设备的分辨率不同,物理尺寸也不同,但你可以通过设置viewport让它们在浏览器里有相同的分辨率。比如说,你的网站是800px宽,你可以通过设置viewport的width=800,来让你的网站在这三个不同的设备上都刚好满屏显示你的网站。
网上一搜关于viewport的知识,基本上全都是如下信息:
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no" />
这段代码的意思是,让viewport的宽度等于物理设备上的真实分辨率,不允许用户缩放。一都主流的web app都是这么设置的,它的作用其实是故意舍弃viewport,不缩放页面,这样dpi肯定和设备上的真实分辨率是一样的,不做任何缩放,网页会因此显得更高细腻。玩ps的同学应该都知道,当你将一张1000 * 1000的图片直接缩放至500 * 500分变成什么样,对吧?图片的失真一定逃不掉。
但我要做的一个应用却恰恰相反,需要利用viewport,利用缩放。不论真实分辨率是多少,无论物理尺寸是多少,我都希望在浏览器里,能有统一的分辨率,同时也不允许用户缩放。我用来测试的设备有:iphone4、ipad2、htc的g11、不知道什么厂商的aquos phone(android系统)、华硕的android pad、dell的winphone然后我一路遇到了如下问题:
1)如果不显示地设置viewport,那么width的默认为980。如果页面的所有元素宽度都小于980,此时width为980,如果页面最宽的位置超过980,那么width等于最大宽度。总之,默认能将整个页面从左到右显示出来。如果设置了viewport,比如,只单纯地设置了user-scalable=no,例如<meta name="viewport" content="user-scalable=no" />,那么ios下width还是按980显示(即默认就会通过dpi缩放),但android和winphone下却不会再缩放了,浏览器分辨率和真实设置分辨率一致。
2)对于ios设备,设置width可以生效,但对于android,设置width并不会生效。ios设备,缩放的比率即dpi是通过你设置的width和设置真实分辨率自动计算的,而android下你设置width无效,你能设置的是一个特殊的字段target-densitydpi,关于target-densitydpi可以参考一下这篇文章:http://hi.baidu.com/j_fo/blog/item/748361279ebccd18908f9d7d.html。也就是说,有三个变量:浏览器width、设备真实width、dpi。 我们简单地用个公式来表达它们之间的关系吧(并非真实关系,简单说明用) 设备真实width * dpi = 浏览器width,这里的三个变量,设备真实width是个我们不能操作的已知值,另外两个变量我们可以设置一个来影响另一个,在ios中,我们能改的是浏览器width,dpi自动生成,而在android中,我们能改的是dpi,浏览器width自动生成。对于android,无论我们如何设置width,也不会对浏览器width产生影响。
ps:这里我另外再说一个奇怪的问题:在htc的g11里(htc的手机我只有这一个,别的没有测),如果设置了dpi而不显示地设置width,则user-scalable=no不生效,即是说:<meta name="viewport" content="target-densitydpi=300,user-scalable=no" />,无法阻止用户缩放屏幕。我们需要显示地设置一下width值,仅管这个值对android下的浏览器分辨屏并不产生任何影响(对ios还是会产生影响的),我们仍然要设置它,而且这个值一定要大于320,如果小于等于320,也无法使user-scalable=no生效。这个问题只在htc的g11手机上出现,在aquos phone没有这个问题。兼容android真是件头痛的事 @_@,未来还不知道有多少坑呢。而在winphone上,结果就更奇怪了:我给viewport的width设一个大于480的值,user-scalable=no就失效了,而设一个小于480的值,user-scalable=no能生效。但无论我给viewport的width设多少值,对winphone真正显示的width却并不产生我预期的影响,通过target-densitydpi也没有影响。设置width,如果小于480的话,屏幕会缩放,但缩小的比例却和我预期完全不一样,我不知道它是按照什么规律缩放的。不知道这是winphone的问题,还是dell实现的问题。
3)这一条和上一条应该是直接相关的:ios设备在横竖屏时,会自动调整dpi,无论横屏还是竖屏,都能保证浏览器width等于viewport中设置的值,所以横竖屏的时候,页面里显示的内容的大小是会自动缩放产生变化的。而android手机在横竖屏的时候,不会改变dpi,在横竖屏的时候,网页不会产生缩放。也正因此,ios可以保证横竖屏页面都不会产生滚动条,满屏显示,而android却无法保证这一点,横着满屏则竖着无法满屏,反之亦然。
4)对于ios设备,如果width显示定义了,而页面最宽的位置超过width的话,width无效,仍按最宽的宽度来显示(不会有滚动条)。但此时会出现一个很奇怪的问题,当你将手机横竖屏切换几次之后,会发现你的页面自动放大了,出现了滚动条,但其实放大后的宽度其实和你设的width也并没有关系。为了防止这种情况出现,你需要将width的宽度设置得比页面最宽的地方更大,或者相同。
11、深入了解iPad上的MouseEvent
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事件的元素只会收到上述后一种事件流,这避免绝大多数链接需要手指点击两次才能跳转页面。一个元素的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文档 :文档在“Handling Events”这一章描述了对MouseEvent的支持。
五、app开发经验谈和实例参考
来源:oschina
链接:https://my.oschina.net/u/565012/blog/88089