Mobile web开发之道

移动web开发之道(Android与Iphone)
1、javascript篇
(1)使用querySelector和querySelectorAll这两个方法获取文档对象中DOM节点的引用


由于这两个方法都是本地方法,因此在执行效率上比较理想

//获得一个id为masthead的对象的引用:
var masthead = document.querySelector( "#masthead ");
//获得id为banner的UL元素下面最后一个LI元素下的A标签的引用:
var anchor = document.querySelector( "#banner > li:nth-last-child(1) > a ");
//获得id为category的UL下面的所有LI元素的引用
var categoryList = document.querySelectorAll( "#category > li ");

(2)采用标准的W3C DOM2推荐的事件监听模型监听事件

//推荐的形式:
window.addEventListener( "load ", function(e){
console.log( "page loaded ");
}, false);
//不推荐的形式:
window.onload = function(e){
console.log( "page loaded ");
}

(3)HTML5 Form3 标准加入细化的表单控件检测功能(如Email、URL、TEL等表单控件),因此可直接使用内建的此类空间的验证

//Email类型的表单控件:
<input id="email " type="email " value=" " />
//URL类型的表单控件:
<input id="url " type="url " value=" " />
//不能为空的表单控件:
<input id="name " type="text " value=" " />
//验证时,调用checkValidity方法查询返回值即可:
if(!document.querySelector( "#url ").checkValidity()){
//failed
}

(4)使用placeholder为表单文本输入框空间提供默认提示值(通常情况下采用脚本操作完成)

为Email类型的表单控件提供一个提示值便于用户识别:

<input id="email " type="email " value=" " />

(5) 如果需要在用户机器上保存数据,而且数据相对比较大,可以考虑使用本地存储对象localStorage完成

相比cookie而言,localStorage具有编程接口友好,存储空间大等优点

//调用示例:
localStorage.setItem( "selectedTabIdx ",3);//增加一项
localStorage.removeItem( "selectedTabIdx ");//删除一项

(6)使用内建支持的JSON API处理JSON数据

var point = {
x:1,
y:1
};
//将point对象序列化为JSON串
// {"x":0,"y":1}
var coordinate = JSON.stringify (point);
//将JSON串反序列化为point对象
var point = JSON.parse(data);

(7)使用标准的window.scrollY接口来获取滚动条上部表示的文档长度

document.documentElement.scrollTop或者document.body.scrollTop在safarimobile下此值为0
(8)使用__proto__属性实现对象继承

var Shape = function(){
}
Shape.prototype = {
draw:function(){
//…
}
}
// Triangle继承自Shape
var Triangle = function(){
Shape.apply(this,arguments);
}
Triangle.prototype = {
__proto__:Shape.prototype,
draw:function(){
//paint triangle
}
}

(9)对基本类型或内建DOM对象的扩展都应建立在对象的基础上

由于智能手机平台的脚本运行环境比较完善和符合规范(如DOM对象都是原生的本地对象,而在常规WEB平台上, IE浏览器的部分JAVASCRIPT对象和DOM对象都是依赖COM组件实现,因此是不能直接扩展这些对象的),例如:去除的字符串首位空白
建议的方法:

String.prototype.trim = function(){
return this.replace(/(?:^\s+|\s+$)/gi,"");
};

调用示例:

var str =  "  string with leading and trailing whitespace  ";
str.trim();

不建议的方法:

var trim = function(str){
return str.replace(/(?:^\s+|\s+$)/gi,"");
};

调用示例:

var str =  "  string with leading and trailing whitespace ";
var str = trim(str);

(10)在WEBKIT手机平台上,使用DOM 对象操作的效率比innerHTML操作的效率要高

因此通常情况下,优先选择DOM对象操作创建DOM树例如向id为xyz的SPAN元素中添加1000链接, chrome在PC上的执行结果为

//采用innerHTML方式创建
var html = [];
for(var i = 0; i < 1000; i++){
html.push("<a href="\&quot;javascript:void(0)\&quot;">"+i+"</a>");
}
document.querySelector("#xyz").innerHTML = html.join("");
//执行时间为22秒
//采用DOM节点对象操作的方式创建
var c = document.querySelector("#xyz"), anchor;
for(var i = 0; i < 1000; i++){
anchor = document.createElement("a");
anchor.textContent = i;
c.appendChild(anchor);
}
//执行时间为14秒

(11)new WebKitCSSMatrix(window.getComputedStyle(dom).webkitTransform) 新建矩阵
(12)DOMSubtreeModified DOM文档树修改时执行事件,兼容IE9、FF、safari、chrom不支持opera
2、CSS篇
(1)使用CSS3 Media Query可以分别为手机横屏模式(landscape)和竖屏模式(portrait)应用样式, 是布局更加合理

#masthead{
Margin-top:10px;
}
/*单独为横屏(langscape)声明样式*/
@media screen and (max-height: 300px){
#masthead{
margin-top:0;
}
}

(2) 使用CSS创建渐变的背景图片

.heading{
background: #F5F7FF -webkit-gradient(linear, 0% 0%, 0% 100%, from(white), color-stop(0.02, #FAFCFF), color-stop(0.7, #F4F6FF), to(#F6F7FF));}

(3)使用CSS3多层背景创建相对复杂的icon

.icon::before{
float:left;
margin:2px 5px 0 0;
content:"\20";
width:4px;
height:14px;
text-indent:-999em;
background-image:-webkit-gradient(linear,left top,right top,color-stop(.0,#9cdbfa),color-stop(.2,#9cdbfa),color-stop(.21,#58b3df),color-stop(.4,#58b3df),color-stop(.41,#007ac4),color-stop(1.0,#007ac4)),-webkit-gradient(linear,left top,right top,color-stop(.0,#9cff65),color-stop(.2,#9cff65),color-stop(.21,#5af703),color-stop(.4,#5af703),color-stop(.41,#46c500),color-stop(1.0,#46c500));
background-position:0 0;
background-repeat:no-repeat;
-webkit-background-size:100% 4px,100% 100%;
}

(4)使用webkit提供的css canvas创建简单图片icon,例如:

预先在内存中创建Canvas对象

(function() {
var a = 8;
var a2 = a / 2;
var ctx = document.getCSSCanvasContext('2d', 'triangle', a2 + 2, a);
ctx.fillStyle = '#46c500';
ctx.strokeStyle = "#46c500";
ctx.beginPath();
ctx.moveTo(0, 0);
ctx.lineTo(0, a);
ctx.lineTo(a2, a/2);
ctx.lineTo(0, 0);
ctx.closePath();
ctx.fill();
ctx.stroke();
})();

使用CSS引用内存中的Canvas对象:

.icon{
background:-webkit-canvas(triangle) 5px 50% no-repeat;
}

(5)采用base64编码创建小图片、icon

3、目前发现的一些bug

(1)G3(Android 1.5)版本touch事件的问题

G3(Android 1.5)版本,触发touchstart事件之后,并没有触发touchmove事件,直接触发touchend事件。在Android 1.5中,手指点击事件触发正常。但是手指移动时touchmove及touchend无法正常触发,可能情况是触发时间不正确或者事件触发不连续。
解决方案:在touchstart事件中,对于事件参数e调用preventDefault方法,阻止触发浏览器默认事件。
一点疑惑:该问题可能由于move的时候浏览器本身IO阻塞了正常程序的执行,后验证确实会这样,例如阻止链接的点击
(2)Android 对绝对定位在文本框上的元素的ontouchstart事件

Android 对绝对定位在文本框上的元素的ontouchstart事件支持有badcase,当手指点击该元素(文本框内的区域)的时候无法触发该元素的ontouchstart事件,针对Android要用onmousedown解决。
(3)iPhone & Android 不支持position:fixed

(4)某些情况下,使用translate3D进行屏幕翻页操作,会导致屏幕闪烁,解决办法,改用普通的translate,但是会没有硬件加速效果

(5)translate 的bug

发现在某一款ios上会出现此bug,itouch的4.1(8B117),发现在使用translate进行翻页时,翻完后屏幕会闪烁下,使用 translate3d可以搞定这个问题,但是translate3d可能引入更多的问题,例如按钮高亮错误,图片渲染bug等,最后google一顿乱 收,终于找到解决办法:

-webkit-perspective: 1000;
-webkit-backface-visibility: hidden;

(6)JS在点击链接时发送图片请求来记录点击日志bug

但如果链接在当前窗口打开,就会出现日志缺失的情况,因为,如果跳转较快,而图片还没来得及创建,改请求就不会发送
(a)先preventDefault,settimeout执行window.location.href=”"
(b)onmousedown时即创建图片请求
(7)android1.6下scalebug,当css如下写时li为img的父级元素,调用scale后页面空白

li{overflow:hidden;float:left;}
img{position:absolute;}

(8)scale会改变坐标系,比较混乱,没搞明白到底什么样的

(9)部分android手机上不能访问内网域名,只能访问ip地址

(10)Android手机window.innerWidth和window.innerHeight的bug

在屏幕旋转时,返回的值并不是当前宽度和高度,而是旋转之前的,通过下面方法可以解决,寻求更好的解决办法:

var orientationEvent=("onorientationchange" in window) ? "orientationchange" : "resize";
window.addEventListener(orientationEvent,function(e){
setTimeout(function(){
alert(window.innerWidth);
},500);
},false);

(11)阻止手机浏览器缩放,在头部设置下述代码,但某些高版本的手机上会失效(G12,G13)

 

(12)字体大小随屏幕旋转而变大,而且只是部分变大

在开发完页面后,在iphone上,正常浏览页面,没有问题,但是当旋转屏幕为风景模式时,发现有些字体变大,而有些则不变,很诡异吧 其实是因为iphone会自适应font-size,解决办法:

html {-webkit-text-size-adjust:none}

(13)translate使用3d坐标时会出现文字渲染的诡异bug

例如在通过translate进行手机上的翻页功能时, 在safari手机可以看到字体变形,不过这个问题在手机上不会出现

-webkit-transform: translate3d(-334px, 0px, 0px);

去掉3d后即没问题了

(14)iPhone & Android 不支持position:fixed

解决办法,android上使用user-scalable设置为no,ios5支持,但是ios 4.2.1不好使,寻求高手指教
4、开发工具

(1)fiddler代理

就像pc端的fiddler代理功能一样,手机上也可以使用代理,这样可以更方便的进行远程调试,更多细节:http://www.lovesunlife.com/?p=127
(2)weinre

这个工具非常的强大,也非常的适用,fiddler只能调试可以使用代理的手机,但目前很多android还不能使用代理,这时候不好调试,所以使 用这时就需要使用wenire工具进行远程调试,我使用的是linux机器,下面是weinre linux调试环境安装方法:
(a)下载weinre https://github.com/downloads/phonegap/weinre/weinre-jar-1.5.0.zip
(b)tc-noah-info1.tc  /tmp/java6.tar.gz下载
(c)解压缩java6
(d)配置环境变量vim ~/.bashrc

export JAVA_HOME=/home/img/liuhui/java6
export PATH=$JAVA_HOME/bin:$PATH
export CLASSPATH=.:$JAVA_HOME/lib/tools.jar:$JAVA_HOME/lib/dt.jar:$CLASSPATH

(e)java -jar weinre.jar –httpPort 8081 –boundHost -all-
(f)运行后会提示访问地址 例如我的http://10.26.204.20:8081/
(g)在要调试的页面引入js:http://10.26.204.20:8081/target/target-script-min.js#lh
然后通过http://10.26.204.20:8081/client/#lh
上面我搭建了自己的服务,其实官网提供了它自己的服务,只是速度会比较慢,更多详情官网了解http://phonegap.github.com/weinre/

(3)各种书签工具

这个工具可以让你在手机中开启firebug调试、yslow等,但我感觉还是比较适合pc端的调试 http://stevesouders.com/mobileperf/mobileperfbkm.php,这是国外一牛人汇总的各种书签包括 firebug lite和yslow等

(4)在手机上调试还是没法断点,这时候可以在safari中通过修改useragent来进行手机上的仿真

偏好设置-》高级-》选中 “在菜单栏中显示开发菜单 “,这时候在导航条中就可以看到开发了,点击开发-》用户代理-》选择iphone,除了通过浏览器本身的设置来修改useragent外,还可以通过 fiddler修改rules-》user-agent》选择iphone,如果没有需要自己进行配置rules-》customize rules,在user-agent的配置项中增加下行代码,

RulesStringValue(17,"&iphone", "Mozilla/5.0 (iPod; U; CPU iPhone OS 4_0 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Version/4.0.5 Mobile/8A293 Safari/6531.22.7")

更多user-agent值可参考: http://www.zytrax.com/tech/web/browser_ids.htm#safari

以上是汇总别人一些目前开发中遇到的问题,及最终解决办法,对于初学mobile web开发的人,建议可以看下面博客,讲解的非常详细:

Part 1: The viewport metatag

Part 2: The mobile developer’s toolkit

Part 3: Designing buttons that don’t suck

Part 4: On designing a mobile webpage

Part 5: Using mobile-specific HTML, CSS, and JavaScript

Part 6: Dealing with device orientation

Part 7: Mobile JavaScript libraries and frameworks

posted @ 2012-03-02 01:00  radom  阅读(2891)  评论(0编辑  收藏  举报