移动web项目开发问题笔记
前阵一直在做的移动web项目项目已进入尾声,以下总结下在项目中遇到的问题和技术要点
开发问题及要点
1. viewport 窗口适应
通过设置viewport使页面适应设备的宽度
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0, minimum-scale=1.0, maximum-scale=1.0">
user-scalable设置用户是否可以修改比例
minimum-scale 最新缩放比例
maximum-scale 最大缩放比例
其他:window.devicePixelRatio 设备物理像素和网页像素-设备无关像素device-independent pixels (dips)的比例
2. js框架的选择
考虑框架体积、学习成本和移植问题,备选框架zeptojs quojs,这两个框架都兼容大部分jQuery API,考虑quojs太新,淘宝手机版也是用的zepto最后敲定zeptojs
3. touch事件
手机触屏web和传统web最大不同就是触摸 需要学习三个基本的触摸事件
touchstart touchmove touchend 对应mousedown mousemove mouseup
zeptojs中进行了封装:tap singleTap doubleTap longTap swipe swipeLeft swipeRight swipeUp swipeDown
在触摸事件对象中增加了多点的相关对象和属性.
如:event.targetTouches[0].pageX 获得第一个点的页面水平位置
4. 关键属性不支持 position:fixed overflow:auto
在项目中需要有个一工具条一直浮在屏幕下方,
使用position:fixed 等效于position:absolute
考虑将上部区域增加滚动条实现效果,发现 overflow:auto 等效于overflow:hidden
在手机上区域(div等块)不会出现滚动条.
解决办法:使用iscroll http://cubiq.org/iscroll
虽然iscroll解决了滚动条的问题,但是也带来了更麻烦的问题
深入问题:
iscroll兼容性及常见问题处理
通病:
由于要通过touch事件模拟浏览器的滚动,iscroll阻止了滚动区域内的所有浏览器默认动作导致输入框焦点无法进入等问题。
解决方法: 在iscroll初始化时,注册以下方法,排除掉需要浏览器默认动作的元素
onBeforeScrollStart: function(e) { var target = e.target; while (target.nodeType != 1) target = target.parentNode; if (target.tagName != 'SELECT' && target.tagName != 'INPUT' && target.tagName != 'TEXTAREA' && target.tagName != 'BUTTON'){ e.preventDefault(); } }
1) 由于使用iscroll页面本身的滚动条就不能出现,导致滚动时浏览器地址栏一直显示.
解决方法:
在页面加载完后通过类似
setTimeout(function(){ window.scrollTo(0, 1); }, 100);
把地址栏顶上去
2) Iphone下拖动input textarea时会出现浏览器默认的滚动条并触发回弹效果
按说在上边onBeforeScrollStart中已经对TEXTAREA等做过处理了这里为什么会出现这种情况?
经过实验在iphone里TEXTAREA 的touch事件都不能正确触发,在其父对象中注册也不能监听到.
解决办法:
情况比较复杂,使用pointer-events,让它们不能响应事件这样拖动的时候实际是拖的它们的父元素,但是会造成焦点无法进入的问题,所以在touchstart的时候再瞬间恢复一下。
$('input,textarea').css('pointer-events','none'); $(document).on('touchstart',function(e){ $('input,textarea').css('pointer-events','auto'); }).on('touchmove',function(e){ e.preventDefault(); $('input,textarea').css('pointer-events','none'); }).on('touchend',function(){ setTimeout(function() { $('input,textarea').css('pointer-events','none'); }, 0); });
ps:这种固定浮动的问题在传统web开发时就一直烦扰着我们(兼容问题),到移动web上更加麻烦,最好能从设计上避开这些问题,另外第三方框架的问题也会很头疼。
5. 屏幕方向判断
移动浏览器上提供了onorientationchange事件和window.orientation属性帮助屏幕方向的判断,但这貌似很简单的功能里也有坑, 注意onorientationchange触发的时候页面并没有转过来这时候获取宽高是不对的,需要在resize事件中获取。
6. html5 动画
动画效果已经不再用setTimeout setInterval二兄弟了, 使用CSS3 transition 就可以了,兼容的问题就交给框架吧zeptojs中动画都是使用这个实现.
参考: http://www.w3schools.com/css3/css3_transitions.asp
变换移动的效果可以考虑使用transform: translate3d可以开启硬件加速
之前一个效果使用的margin来实现的,在android上没问题在ios上竟然会卡,换translate3d问题解决,虽然获取值麻烦点,随手粘个获取x的值:
scroller.css('-webkit-transform').match(/translate3d\((.*?)px,.*?\)/i)[1]
7. android2.X多点问题
试了很多声称支持pinch的框架在android2.x都残念
根本原因是浏览器event.targetTouches中只能返回一个触点,见以下
http://code.google.com/p/android/issues/detail?id=11909
8. android2.X获得分辨率问题 screen.width/height
screen.width/height不能正确返回设备的像素数
http://code.google.com/p/android/issues/detail?id=12455
9.android原生浏览器input textarea输入时滚动条乱动
页面中有节点样式包含
-webkit-transform: translate3d(0px, 0px,0px) 时会发生
解决办法:
不使用translate3d() 改为 translate(0px, 0px) translateZ(0px);
10.iphone5 webapp不能全屏,在状态栏上部出现黑色区域
参考:https://gist.github.com/burin/3840737
解决办法如下(包含欢迎图片解决方法):
- <link href="assets/splashs/splash_1096.png" rel="apple-touch-startup-image" media="(device-height: 568px)">
- <link href="assets/splashs/splash_iphone_2x.png" rel="apple-touch-startup-image" sizes="640x960" media="(device-height: 480px)">