New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
移动Web单页应用开发实践——页面结构化 #8
Comments
@mark 一下 |
写的不错!学习了~~ :D |
@maxzhang 顶起~~~~ |
mark~ |
这篇文章基本上就是手把手教大家如何做移动端的 web app 布局了,谢谢分享,非常棒! 我贡献一点勘误:
这里的“属性”应为“刷新”。
这一段的示例代码中的 CSS 应该有误,比如 建议其它的 CSS 代码也可以再校对一下。 |
iScroll 5 还没有试。不过我打算在 iOS 5+ 和 Android 4+ 上用原生的区域滚动替换掉它,因为较新的浏览器已支持 |
@cssmagic 谢谢提醒,iScroll5的代码我看过,相比iScroll4改进不少,而且现在一个趋势,就是Android的浏览器性能越来越好,iScroll运行得比以前要流畅很多。 |
mark |
2 similar comments
mark |
mark |
最近做mobile app框架和应用,经常参考搜狐触屏版,学到很多技巧和经验,分享一下SPA框架 https://github.com/zhaoda/spa |
@zhaoda 期待多交流,微博求互粉 @炎燎 |
@maxzhang 已关注 |
mark~ |
1 similar comment
mark~ |
好资源,学习了 |
mark |
说到性能,Chrome for Android明显比Android Browser要好。 |
這邊可以參考一下 :) 2013/11/3 HE Shi-Jun notifications@github.com
|
@hax 移动设备的性能现在越来越好,早在半年前关于IScroll的一些观点,现在也有不同的新想法,移动设备更新速度远比我想像的要快得多,而且移动浏览器的发展很快,UC和QQ能做到半年就更新一个大版本,每次大版本的升级都能得到很好的性能提升与新特性的支持。 我不太同意认同Android是XP的说法,当下即使在低端设备运行Android2.x的系统下面,高版本的UC、QQ也能有不错的处理性能和体验。 |
mark |
赞! |
在iscroll5正式发布后,作者还是坚持在安卓上不使用iscroll的方案吗? |
@maxzhang 我不上微博,有时候上知乎,我去知乎follow一下你吧。 |
mark |
1 similar comment
mark |
好文章,谢谢分享。 |
我想问一下,安卓2.3不支持overflow,怎样在非body上使用overflow?或者只能把content放在body上滚动? |
@maxzhang absolute的元素也里面的input,安卓下也会出现不上弹的情况,软键盘盖住input,这种情况怎么破? |
@Jokcy 修改下设计,将input的位置往上调, |
楼主写的非常好,学习了。 |
@maxzhang 感谢非常精彩的分享,受益匪浅; 新手有个问题请教一下: 我看手机搜狐版(http://m.sohu.com/n/406721112/?wscrid=1137_1) 都是通过刷新来切换到下一个页面; 问题一: 问题二:
|
@chenbin92 |
干货! 果断mark |
好文!学习了~ |
cordova 开发菜鸟路过…… |
好文!学习了~ |
赞一个,学习了 |
学习了~ |
mark |
1 similar comment
mark |
不得不赞! |
赞 |
不知道那个blur后position定位问题如何解决的 |
对于移动端Fixed布局的话,整体思路可以是保证页面布局的整体高度不大于手机屏幕的高度,content设置成overflow,header+content(可是区域)+footer <= window.innerheight,就可以解决了 |
mark 赞! |
mark 赞!!! |
赞!! |
mark |
1 similar comment
mark |
好文~谢谢无私分享! |
mark |
1 similar comment
mark |
重定向:http://www.maxzhang.com/2013/09/%E7%A7%BB%E5%8A%A8Web%E5%8D%95%E9%A1%B5%E5%BA%94%E7%94%A8%E5%BC%80%E5%8F%91%E5%AE%9E%E8%B7%B5%E2%80%94%E2%80%94%E9%A1%B5%E9%9D%A2%E7%BB%93%E6%9E%84%E5%8C%96/
移动Web单页应用开发实践——页面结构化
1. 前言
在开发面向现代智能手机的移动Web应用的时候,无法避免一个事实,就是需要开发单页应用(Single Page WebApp)。对于不同的系统需求,单页应用的粒度会不同,可能是整个系统都使用一个页面装载,也可能是按模块分为独立页面装载。在开发单页应用时第一个要处理的问题就是页面结构化,由于多个功能集中在一个页面呈现,就必然需要考虑如何实现多个视图布局?如何实现视图之间动画切换?等问题。
下面我就来讲述下手机搜狐前端团队在单页应用开发的页面结构化上做过的一些尝试与努力。
2. 页面视图
在讲页面结构化之前需要先理解视图的概念,视图是单页应用开发中最常见的模块,通常在一个单页应用中,会有多个视图存在,每一个视图都可以处理一部分业务功能,所有视图的功能集就是单页应用所能处理业务的最大能力。下面介绍几种单页应用中最常出现的几种视图。
2.1 单视图层
三段式结构是单视图的一种最基本布局方式,如下图:
单视图并不一定都有head或foot,所以Header、Footer使用虚线来表示。多数应用中还会有导航条(Navigatior),但一般情况下导航条会被计算为Header或Content的一部分,而不会独立存在。
2.2 侧边栏
侧边栏是一种特殊的视图,在不显示时,当前视图是盖在侧边栏至上的,当它被呼出时,视图一部分滑出屏幕外,侧边栏才被显示出来,它的高度等于页面可视区域的高度。
显示前:
显示后:
2.3 封面图
封面图与侧边栏类似,也是一个特殊的视图。封面图一般会在页面初始时候出现,而后消失,消失之后就不再出现。它的视图层级是最高的,并且完全覆盖于其他页面元素,它的高度会大于或等于可视区域的高度。
3 多视图布局
单页应用中第一个要思考的问题就是:如何实现多视图的布局?通常我们会将视图的定位设置为
position:absolute
,这是一种简单又实用的方法。在一个时间节点上,页面可视区域只能有一个可见的当前视图,虚线表示其他视图,在页面可视区域之外不可见(display:none
),如下图:使用伪代码表示:
此时,我们需要思考另一个问题:如何实现当前视图的Content区域内容滚动?视图的样式高度设置为
height:100%
,将视图高度设定为一屏高的目的是为了方便实现视图动画切换的效果(视图动画切换会在后面详细的讲)。但这样做会导致另一个问题,高度为一屏高意味着浏览器滚动条失效,无法使用浏览器滚动条滚动页面。3.1 基于iScroll的多视图布局
现在比较流行的一种解决方案是使用iScroll组件实现固定区域滚动,这样就能解决Content区域的滚动问题,在手机搜狐的早期项目也是这么做的。此外,使用iScroll还额外带来了一些好处,如:
对于这种结构的应用,在使用视图切换的时候就非常好做,使用CSS3的transition来完成动画切换,如下图:
使用伪代码表示:
视图切换的动画效果可以根据业务需求定制,比如:由左向右滑动、由右向左、由上到下、右下到上等都是可以的。在完成切换动画时,再将next视图的状态设置为current,如下:
下图是项目中使用的一个由下往上动画切换效果:
3.2 iScroll页面结构下的侧边栏
使用iScroll的页面结构,无论是侧边栏还是封面图都非常好实现,看伪代码:
侧边栏,默认状态
侧边栏显示时
侧边栏隐藏时,当hide动画结束之后,移除hide样式
3.3 iScroll页面结构下的封面图
封面图的实现与侧边栏差不多。
封面图,默认状态
封面图显示时
封面图隐藏时,当hide动画结束之后,移除hide样式
在项目中的实现效果:
3.4 iScroll对内容刷新的支持
对于Content区域的内容刷新iScroll也有很好的支持,可以直接参见iScroll提供的例子:http://lab.cubiq.org/iscroll/examples/pull-to-refresh/
**Note:**iScroll目前已经更新到了5.0的版本,大家可以关注Github项目https://github.com/cubiq/iscroll/
4. 多视图布局,新的探索
对于单页应用来说,iScroll确实是一个非常优秀的解决方案,但是iScroll缺有一个最大的缺陷——慢,滚动的性能与浏览器原生实现相比,在低端的移动设备上有明显卡顿,这点我在另一片博文中也提到过《移动Web产品前端开发口诀——“快”》。
**Note:**目前有一个新的趋势,浏览器经过一两年的发展,Android下已经优化的相当不错,iScroll在一些较低端的移动设备上,性能表现得比以前要好非常多,比如小米1,早期的米1还在运行UC7.x的版本时,iScroll明显的卡,现在在UC9.x下,iScroll也能运行得比较流畅了。
4.1 Fixed+原生Scroll
在此之下,我们也做了一些新的尝试,第一尝试就是放弃使用iScroll组件。放弃之后遇到的第一个问题,如何使Header固定位置在顶部?由此,我们使用了原生的CSS特性
position:fixed
,如下图:Fixed在一些移动设备浏览器上有兼容问题,我找到了一种能检测浏览器是否支持position:fixed的方法,这个也发一篇博文《移动Web开发,4行代码检测浏览器是否支持position:fixed》,在检测到浏览器不支持fixed时,可以使用absolute作为替代方案,监听window的scroll事件,每次scroll动作结束时,重新计算一次Header的top值,将其定位到页面顶部。
有关
position:fixed
的bug在另一篇博文中《移动端web页面使用position:fixed问题总结》也有总结。另外强调一点,不要在Fixed区域中直接使用input或textarea元素。在fixed元素中的input获取焦点之后,弹出软键盘会带来很多额外的问题,如:
点击input弹出一个新视图来完成后续输入,是一种比较好的解决方案,下图是一个基于iScroll的页面结构实现:
4.2 原生Scroll下的视图切换
使用了原生Scroll之后,带来最大的改变是视图切换动画的变化。使用iScroll的页面结构,视图的高度固定,并且是
position:absolute
定位,所以非常容易做视图切换。换成原生Scroll之后,想使用一个比较缓和的动画过渡效果是非常困难的,可选的动画效果十分有限,经过了很多试验之后,最后选择使用淡入-淡出的动画效果,这是一种折中的方法。最初在完成这种动画实现的时候,编码的方法比较简单,就是将当前视图淡出,下一视图淡入,如下图:
后来在做了更多尝试之后,开发出了一种兼容更强的淡入-淡出动画过渡。技术要点就是使用一个幕布层(mask)实现淡入效果,在mask完成淡入之后,再完成实际的视图的切换,操作步骤大致如下:
<div class="mask"></div>
,mask为position:absolute
定位,初始为透明状态,背景设置为白色或其他颜色,并使mask盖在当前视图上面;opacity:1
的动画过渡,当完成动画时,mask将会把当前视图完全遮住;效果图:
4.3 原生Scroll页面结构下的侧边栏
侧边栏的结构也变得复杂了一些,使用原生Scroll之后,body的高度会被内容区域撑到很高,但侧边栏还是必须保证一屏高。所以我在侧边栏显示时,将html与body的高度控制为一屏高,这样可以防止页面被滚动。使用伪代码表示:
侧边栏,默认状态
侧边栏显示时,在html元素上增加一个样式sidebar-show
侧边栏隐藏时,将html元素上的样式替换成sidebar-hide,当hide动画结束之后,移除hide样式
在项目中的实际效果:
另外,将侧边栏设置为
position:fixed
定位会是另一种实现思路。4.4 原生Scroll页面结构下的封面图
封面图的实现与侧边栏差不多,使用伪代码表示:
封面图,默认为显示状态
封面图隐藏时,将html元素上的样式替换成cover-hide,当hide动画结束之后,移除hide样式
项目中的应用:
4.5 原生Scroll页面结构下,内容刷新的实现
一般情况下,我们会页面底部放一个加载更多的按钮,让用户点击按钮加载下一页内容,如下图:
又或者,监听window的scroll事件,当页面发生滚动时,监测是否滚动到页面底部,自动加载下一页内容。这两种方式都能很好的解决加载下一页的业务需求,但是对于加载最新或刷新的操作只能在页面中放置一个刷新按钮来完成业务需求。
对于Pull Up/Down Request的操作,在原生Scroll下,几乎是无法实现的。但我依然希望能找到一种方法,实现Pull Request操作。
现在我正在研究一种模拟Pull操作的解决方案,已经有了一个雏形,并实现了一些功能。下面这个示例中没有使用任何的iScroll技术,完全使用原生Scroll实现页面滚动,并且滚动到页面底部后可以完成Pull Up操作,如下图:
这个技术的实现原理并不复杂,就是在页面滚动到底部时,创建一个空白层,模拟Pull Up手势拖动页面的效果。
我后面会封装成一个组件放在GitHub上分享给大家。
5 结束语
手机搜狐目前还是一个年轻的前端团队,在手机搜狐的一年半时间,积累和很多有关移动端Web开发的经验,写这篇文章希望能将自己在移动Web方面的一些经验分享给大家,同时,也希望能有更多的移动Web开发者能互相交流。
Note:文章中的伪代码也许不能完全正确运行,只是提供一种解决问题的参考和思路,实际处理过程远比伪代码要复杂得多。
The text was updated successfully, but these errors were encountered: