技术头条 - 一个快速在微博传播文章的方式     搜索本站
您现在的位置首页 --> JavaScript --> 一次响应性开发实践

一次响应性开发实践

浏览:1396次  出处信息

响应性开发的概念不做细述,一年前曾做过一次分享”聊聊响应性设计和开发“。
仅仅利用media query适配样式是远远不够的,并没有考虑触屏下的行为和特有的内容组织方式的不同。简单在桌面版基础上叠加mobile版的代码,会带来请求增多、流量、性能、代码冗余等诸多方面问题。

这次从以下几个方面着手,充分发挥“响应”的灵活性,目标是得到一个更“好用”的体验。

1. 响应性的模块
原本网站的模块化程度越高越便于做响应性开发。一个page例如是这样组织的:

<%include file="path/mod1.html" args="data=data" />
<%include file="path/mod2.html" args="data=data" />

如果在手机下访问,模板系统在生成这个页面时,会在path/下找mobile.mod1.html,有则加之,否则加mod1.html。也就是说在同一目录下,会存在多个版本的模块,当前只有2种:mod1.html(桌面版),mobile.mod1.html(mobile版)

响应部分的代码,跟主站代码是放在一起的,这样更便于维护。一个页面模板的结构是这样的:

page1.html:
<%inherit file="/base.html" />

<%def name="main">
桌面版主要内容
<%include file="path/mod1.html" args="data=data" />
</%def>

<%def name="sidebar">
桌面版边栏内容
</%def>

<%def name="mobile_main">
<%block filter="collect_css">
mobile版css
</%block>
mobile版主要内容。如果可以复用,直接调${self.main()}
很多情况下内容是不同的,比如去掉不必要的模块。
</%def>

<%def name="mobile_sidebar">
mobile版底部内容
</%def>


这意味可以同时开发/维护两个版本。(同样,设计师在设计一个页面,也需要秉承mobile first的原则)
在同一目录、同一文件维护比分布在不同的仓库中要方便的多。

2. 响应性的css/js
mobile版的变化很大,在样式上并不是桌面版css+mobile版css的关系。这得益于我们之前对静态文件管理系统的改造。传统的css的组织方式是集中式的,集中在几个通用文件中,形如base.css + product.css。而我们现在的方式是base.css + mod_1.css(inline) + mod_2.css(inline) + mod_3.css(inline) … 是按需组合的形式。

这样,加上设备判断后就可以轻易变成:
mobile.base.css + mobile.mod_1.css(inline) + mobile.mod_2.css(inline) + mobile.mod_3.css(inline) …

css/js文件跟模板一样,在同一目录下分别有桌面版和mobile版。根据访问端的情况,自动适配、按需组合。这样可以得到一个更优化的mobile站。

3. 增强触屏行为和兼容桌面事件
前者是指附加触屏上特有的事件:touchstart/touchmove/touchend以及手势swip/pinch/rotate/shake。这个不是难点。

mobile浏览器和桌面浏览器的事件模型有明显差异,为了完全复用桌面版的各种js组件,首要问题是设法兼容桌面事件(click和mouse事件)。

mobile上的click和mouse事件有几个需要注意的地方:
a. click和mouse事件不会发生在不可点击的元素上,意味绑在document上的事件代理完全失效
b. mouse事件是发生在手指离开屏幕后,且顺序是mouseover > mousemove > mousedown > mouseup
c. click事件最后触发。从手指离开屏幕起,有约300多毫秒延迟,而且有可能不会被触发

见下图:

“If the user taps a clickable element, events arrive in this order: mouseover, mousemove, mousedown, mouseup, and click. The mouseout event occurs only if the user taps on another clickable item. Also, if the contents of the page changes on the mousemove event, no subsequent events in the sequence are sent.”(出处)

android/ios不支持beforeunload事件,对unload事件的支持有些怪异,需要用pageshow/pagehide事件替代。

以上事件的差异都是要尽力消除的。解决思路是利用jQuery的special event机制覆盖掉原本的事件绑定。即:node.click(fn),mobile上转向node.touchend(fn) 。实现的代码:https://gist.github.com/3358036

4. 优化和用户体验

a.去掉了apple-mobile-web-app-capable声明。单页应用要加上,用响应式开发的加上这句体验反而不好,跳转的链接会弹出窗口打开。

<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no">
<meta name="format-detection" content="telephone=no"/>
## <meta name="apple-mobile-web-app-capable" content="yes">

b. “If the user taps a nonclickable element, no events are generated.”(引自Apple Dev Center),所以:

body {
cursor:pointer;
}

c. 设定内容中图片的最大宽:

.topic-content img {
max-width:100%;
}

d. 加载提示,感觉像异步加载。

e. application cache本身是为web app设计的,在响应式开发中的应用是不同的。
把大文件在手机端cache起来:

CACHE MANIFEST
# version 0.0.1
CACHE:
${static('/js/jquery.min.js')}
${static('/js/do.js')}
${static('/css/mobile/base.css')}
${image_url('/pics/icon/dou.png')}
${static('/css/ui/dialog.css')}
${static('/js/ui/dialog.js')}
${static('/js/mobile/jquery.mobile.events.js')}

这个文件是动态生成的,好处是当文件更新后,文件名中的签名会跟着变,也就会触发手机端app cache的更新。

判断cache更新:

if (window.applicationCache) {
window.applicationCache.addEventListener('updateready',function(){
window.applicationCache.swapCache();
}, false);
}

为了避免动态页面被cache,在一个隐藏的iframe里指定它。

f. mobile上的UI库,比桌面版更有必要。

响应式开发最大的优点是投入产出比高。可以高效的把产品向各种终端设备上部署,而且使用体验也可以做到不错。这只是探索的开始。
用手机访问:http://group.douban.com

QQ技术交流群:445447336,欢迎加入!
扫一扫订阅我的微信号:IT技术博客大学习
© 2009 - 2024 by blogread.cn 微博:@IT技术博客大学习

京ICP备15002552号-1