2008年1月27日星期日

Geeky meets Pretty

因为我在北京的圈子里认识不少geek,同时我又想认识靓女,所以就采取了这样一种策略──估计那么多geek都想认识靓女,所以就搞一个party吧,各自把自己认识的靓女都带过来,那就可以大家都可以认识到更多靓女了。也因此,party被命名为Geeky meets Pretty。

这次的party星期四早上第一次讨论,然后就确定星期天晚上搞了,效率异常高。我其实是担心准备不充分的,不过快过年了,也就没办法拖了,既然星期天晚上没问题,那就星期天晚上吧。开头我们预计5位geeky至少各自带以为靓女来,有10个人,搞一个小规模的party,不过最后来了15个人,证明人数并不是一个需要担心的问题。

对于这次party,从geeky到pretty,按1到10打分的话,我会给2或者3。在讨论的话题上,其实不算geek,只有一点点IT而已,因为在场的男士都是IT圈子里的,说到PR女士就郁闷了──在说Public Relation吗?不是,是Page Rank。然而,整个party的娱乐性不算高,一群高智商的人聚会,娱乐项目自然是杀人。杀人游戏要求思维运转,不过娱乐性就一般般了。这次的party没有任何的酒精,也没有什么很刺激的游戏,这是我觉得娱乐性低的一些原因,就是现场很文明,一点都没有high的感觉。看起来更像是IT界的聚会,可惜大家又不讲IT,所以有时候也会冷场。

因此,如何搞好一次party,其实是非常有学问可言的,我的意思是对于我们这些geek来说,有些人天生是party animal,那是我们无法比的。就好像都是MVP,是否擅长交际是人人不同的。Bean在三亚时跟我说,你看哪个MVP是不怎么social的,你就知道他主要是做线上活动的了,因为做线下活动的MVP都是很活跃的人,而作为职业讲师就更加需要懂得如何调动听众的氛围了。暂时我自觉觉得能够条理清晰地讲好一场讲座,但是不能做到新东方讲师那样15分钟一个笑话,如果我要获取那样的技能,前期我必须主动的去做准备,例如每场讲座之前先精心挑选若干适合插播的笑话。讲着讲着就能自然插一个笑话,这种境界对我来说是难以直接通过不主动背笑话而获得的。

这看起来和我向来坚持的英语学习方法所不同。学英语我不觉得有必要刻意背单词,反正用的频率越高,说明那个单词对你也就越有用,你也就越容易记住它。然而问题是,英语你平时可以不停地用,如果你平时不怎么使用英语,然后考试机会就那么稀有,你就只能通过背来准备。对于演讲和party,我乐意不停地花时间去参与,然后潜移默化地把一些技巧记忆下来,然而这样的机会不存在啊,我不能每天都去演讲,我也不能每天都去party,就算我时间上能够负担得起,也没有这样多的机会。演讲没有听众可以找镜子,party呢?因为party的机会实在太有限了,所以我要组织一次party,我就必须提前做好准备。这次准备不充分,娱乐性不足,下次我就要做足功课再来。

最后,我要感谢awyuanchengyou xujunyu布丁等人,感谢大家参与到组织一个party的工作上来,帮忙选定了party的场所,预定了包间,拉拢了靓女,以及埋了单。

2008年1月24日星期四

Zhuantie 与 Jinghua - 中国互联网文化的重要元素

既然有人研究GuanxiGanqing,那么我就来研究Zhuantie与Jinghua。

首先来说说Zhuantie(转帖)。上次和王兴等人的讨论中,说到为什么百度贴吧只允许吧主上传视频的做法比大众型视频站更有效利用资源。这是跟中国的文化背景有关,中国人中乐于创作内容的或者乐于贡献内容的暂时还非常有限。曾经在Wikipedia上见到有人说,下一代人叫做P代,P指Participate,大家都参与到Wikipedia贡献内容了。然而在中国,还要多少年才能把一代人称之为P代这很难说,现在大多数人还是缺乏创意,缺少闲暇时间去创作,大多数人对着摄像头连装cool的创意也缺乏,高质量的原创视频当然就少。在这个前提下,一个YouTube类的网站就难以通过UGC发展起来了,因为根本就没有UGC,变成了纯粹的转载站,所有人都是将他自己觉得还的视频再发布过来,而非发布自己的内容。而这就是所谓的Zhuantie文化──在中国,由于UGC的缺乏,变成少数内容被不断的复制粘贴,导致整个中国互联网上的内容缺乏多样性。

而被Zhuantie的内容是什么呢?这就是所谓的Jinghua(精华)了。国外的论坛系统是没有所谓的“精华帖”这一设置的,只有sticky用于发布公告。为什么需要精华呢?因为国内论坛的水化问题太严重了,没有哪个帖子不跑题的,而国外论坛很明确规定off topic就一律砍,你有新话题一律开新thread,不要再原来的thread上追加。这样一来,国内的论坛就难得有一个帖子是真正专注于一个话题,能够有所深入探讨的,因此一旦能够出一个这样的帖子,就变成精华了。

2008年1月23日星期三

请不要在 taxi 上使用谷歌地图

谷歌地图(而非Google Maps)的数据源Mapabc非常不精确,已经试过两次了,在北京去一个陌生的地方,在的士上打开J2ME版的谷歌地图,搜索出一个地点来,然后指示司机开过去,而结果表明那是一个错误的地点。虽然北京的士司机很不靠谱(停在红等前拿本地图出来看的都有),但是谷歌地图更不靠谱。

有人说,百度的数据源Mapbar同样不精确,因为中国的一切地理数据都属于“国家机密”,因此需要经过扭曲后才能发布。什么叫做扭曲?这样说吧,用过PDA的人都知道如何校正触控笔的,因为PDA屏幕的显示与触感两个层都是线性的,一般三到五个点就能校正。然而中国公开到网上的地理数据,例如一个城市的地图,你把这张地图叠加到Google Earth的同一个城市之上,然后采用类似的方法来校正,你会发现极难对齐。理论上,如果两张地图都是正确的,只要比例和位置校正了,叠放在一起应该是每一个点都对齐的。我们暂且假设Google Earth拍出来的照片比例误差不会太大,那就说明Mapabc的数据源是有问题的。当然,上述都是听说会来的,我还没亲自做过Mapabc的地图校正。

这就是安全与便捷之间的trade off,你要增加一样就必须削减另外一样。如果你询问普通市民,他们肯定都优先选择增加便捷性的,因为安全问题暂时不觉得有多严重。这和企业内的信息安全问题一样,所有员工都会觉得企业的安全策略(例如每3个月改一次密码)是一种负担,从而想尽办法绕过去。

2008年1月22日星期二

大忽悠争霸战 Round 1 - DING!

aw在一篇关于学习英语的好处的文章里说到,有很多细小的题材只有英文文章才有所涉及,而在中文领域不一定有人研究过,甚至不一定有相关文章。而且,aw说中文文章经常有些是没有科学依据或者缺乏引用出处的,我将此理解为“忽悠”,那么我们现在就来看看谁更忽悠。

aw的后一篇文章的标题是:好消息 - IE6将退出历史舞台。世界上竟然有这样的好事,而我不知道?我一定要过去看看,然后我看了aw的文章,也看了他引用的中英文原文(英文来自InfoWorld,中文来自Solidot,Solidot到底和Slashdot是什么关系我并不清楚),结论就一个:要么aw被Solidot忽悠了,要么aw在忽悠别人,到底是哪个呢?

InfoWorld的标题是Microsoft warns businesses of impending autoupdate to IE7,意思是“Microsoft警告,商业用户即将自动升级到IE7”。然而,Solidot的标题却是“微软将在2月12日把浏览器强制升级到IE7”。这种翻译方法叫做什么?提示:不叫“翻译错误”。没错,那就叫做“忽悠”。“自动升级”就相当于“强制升级”吗?即使你不理解前面的“商业用户”是指什么,这两者的差别也显而易见。

接下来,我就InfoWorld的文章解释一下所谓的“商业用户”。所谓的商业用户,就是指文章中提到的WSUS用户,而什么是WSUS到Microsoft的官方网站看一下就知道。简单来说,你的企业中有一万个Windows客户端,它们都要做Windows Update,然而如果它们都从官方站点进行Windows Update,这浪费多少企业对外的流量,于是你可以选择使用WSUS──一个企业内部专用的Windows Update服务器平台。作为企业的IT管理人员,你首先在企业内部署一台WSUS,让它从Microsoft的官方网站自动下载Windows Update,同时用WSUS生成一个小小的安装包派发给每一个客户端安装一下。在所有的Windows客户端运行该安装包后,它们的注册表都会加上一个标记,告诉它们以后Windows Update不要从Microsoft官方网站下载,而从企业内部的WSUS获取。

这样做有什么好处?记住,在高度IT化的企业内,IT部门就是克隆人军队的指挥官,而所有客户端机器都是克隆人。举个例子,如果你企业内部的ERP平台依赖于IE6,在没有WSUS的情况下员工可能就会无意地通过Windows Update升级到IE7了,然后发现ERP平台用不了,这时IT部门就要被“打扰”了。这类情况一旦增多,“打扰”就升级为“骚扰”了。所以,作为指挥官的IT部门,有权选择“我知道IE7的存在,但不允许任何克隆人升级到IE7,它们也看不到IE7这个升级的存在”,然后所有“升级到IE7并与ERP平台不兼容”这一问题就不会发生了。如果员工自己下载一个IE7的安装包来安装呢?不要以为Microsoft和企业的IT部门是吃饭不干活的,Windows中复杂的组策略设置就是干这个的,IT部门可以定制一个组策略不允许员工装软件,或者不允许员工装IE7。记住,客户端机器就是克隆人,要么清一色IE6,要么清一色IE7,异类统统枪毙!

现在,大家理解什么是WSUS了吧,那也就应该理解那个“警告”的用意了──如果你是企业的IT管理人员,现在最好马上做调研以决定你的企业是否适合升级到IE7,如果不适合你需要提前设置WSUS以避免这个“自动升级”的过程。

当然,国内的企业,包括大型IT企业,其自身的IT化程度还不高,所以没有人理解WSUS以及类似的自动化流程,以为一切就应该是手动的操作,Microsoft的设计一切都是那么“蠢蛋”的,然而事实上谁才是真正的“蠢蛋”?我看是国内某些习惯手动操作并且不怎么理解“国外先进的科学管理流程”的译者吧。Solidot把InfoWorld和Slashdot都引用了,人家两篇文章都说明了这是Microsoft对企业IT管理人员提出的一个“警告”,它自己却在那里坚持说“强行升级”,这真是绝顶的忽悠,你看这带着6点PageRank的aw也中招了。

我在这里可以对Microsoft的客户划分再补充一下。MVP分为三个大类:第一类人的工作是,决定企业购买Windows服务器还是Linux服务器,研究哪个的使用成本更低;第二类人的工作是,在第一类人选择了Windows之后,判断企业内部管理平台到底是否基于Web,是否要引入RSS支持,以最低成本实现效率最大化;第三类人的工作是,在第二类人作出判断后,开始设计、编码、测试、维护那个可能支持RSS的Web平台。在中国,第三类人是最被人广泛了解的,第一类人如果挂个CXO的头衔也为人广泛了解了,而第二类人通常就被无视了。

2008年1月21日星期一

最 Geeky 的企业内部首页

首页嘛,有很多中方案,例如iGoogle式的,足够大众化。PageFlakes或者Netvibes也差不多。但是说到geeky,我有个不错的注意。

Opera提供一个Speed Dial,将1~9对应9个链接,而非将一大堆常用功能扔出来,这不错。根据2/8原则,就算我收藏的链接再多,就算我放在iGoogle首页的模块再多,我要用的就那么几个。因此,我设计的geeky首页就一个speed dial。就这样?当然不是,我希望首页不仅仅能做speed dial,还能做普通的dial。

好像普通的手机键盘那样,长按才是speed dail。例如长按4(ghi),那就打开Google;按4(ghi)6(mno)就打开GMail。然后,如果自定义首页只能打开URL,那就太无聊了。现在整天都要打开内部通讯录,查某个人的电话,然后拿起电话来拨号。我觉得我直接在Web界面上拨号就好了,然后自动转为Skype拨号。每人拿一个Skype手机……算!手机太大了,每人拿一个Skype耳机,假如wi-fi模块能够做到耳机里面的话。只要在首页输入电话,就自动转为Skype拨号,并且转接(或回拨)到我的Skype耳机上,那就够好了。反正公司内部wi-fi覆盖,走到哪里都一样,不会再出现打电话给某人发现他不在固话附近的情况。如果已经有了wi-fi覆盖这样的好事情,再搞一个固话网络或者3G接入,那就多余啦。

当然,有时候还是要查找某个人的电话号码,或者某个文档的信息,这时候不要输入数字,而先输入英文字幕(或者先输入数字0),然后就开始进行企业内部的全文检索。例如有人想找我的分机号码……还什么分机号码呢,我是说Skype号码,那就输入“Cat Chen”,然后就查到了,接着点一下就转到他的Skype耳机上拨号了。

2008年1月18日星期五

MacBook Air 如果可以这样子用就很 cool 了

大家都在谈论MacBook Air,我也来评论下这个东西。大家肯定对那个从大信封里拿出MacBook Air的情景印象深刻吧,我来提供一个理想的用例。

香港的黑帮电影中,你可以看到两方boss会面时,各方boss都会没收所有跟班的手机,然后装到一个大信封里,并且从另外一个大信封倒一堆手机出来,让大家个人拿一个,以确保没有人泄密。

如果MacBook Air足够便宜,boss会面前跟大家说,谁还没有电脑的,然后叫秘书搬一堆大信封进来,一人扔一个(“扔”这个动作很重要,这样才够cool),然后大家打开后发现里面装的是一个MacBook Air,那就爽了!

2008年1月15日星期二

原来我住的是百万豪宅!

其实我从来不在blog里写这样的话题,不过这个比较讽刺,所以说两句。我现在和另外3个在同样是在百度的广东人合租一个房子,房龄和我差不多大,不过竟然买卖时的交易金额能够飙升之百万,真是神奇。我们现在¥3400/月把它租下来了,淡季,离奥运还有半年,所以租金算是便宜,却最近才发现原来我们住的是如此值钱的房子,真是神奇!

出名有两种途径

首先,这是Benny在若干年前说的,不是我说的。想要出名,有两种途径,要么互相吹捧,要么互相攻击。没错,他这说法就把所有可能性都囊括再内了,事实上无论你是主动想成名,还是凭借实力成名后想保持身份与地位,这两样都是你的选择,也是你近有的选择。

我们可以看得到,有些业内“知名人士”,时不时发表一些其实没什么深度的文章,里面其实都是对业内其他名人的……这么说吧,就是他表现得在其他名人面前尤为谦虚的样子,这其实就是第一种途径了。你想想,如果你捧一下别人,那个人可能不感恩也来捧一下你吗?这当然可能,因为对方真的可能就是实事求是的人。然而你捧一百个呢?里面总有几个和你一样处于某种尴尬地位的,或者说是瓶颈,论实力想再提升上去有难度,于是干脆就顺你意和你一起玩这个互相吹捧的游戏,反正他也有好处。

另外一种途径,就是找个名人下手,开始攻击他,例如找Keso啦。先不说Keso到底是否有实力,这不是重点,重点在于他出名,那就够了,你就可以用他来做攻击目标,从而推动你的名气上涨。如果你只是一群暴徒中相对“默默无闻”的一个,那没什么作用,但如果你是领头人,你攻击别人的言论足够“一针见血”,那就成功了。正所谓“敌人的敌人也就是朋友”,那位名人的反对者就会站到你这一边来。也就是说,你只要不至于蠢到找一个人缘超好的名人来做攻击对象,找个性格分明的,他肯定有自己的反对派,你一攻击,就相当于把他的反对派拉到你这边来了,多好。

因此,国内的IT圈子有时候也挺像是娱乐圈,谁玩谁还不知道呢。我作为一个MVP,有时候也不得不随大流结识一下圈子里的其他人,例如去认识一下Keso。不过说到底,最值得仰慕的,还是那些真正靠实力而成为geek的人。

2008年1月10日星期四

Windows 就是一个带 UI 的命令行

这是用过Mac之后对Windows的感觉。

用一个对程序员来说比较友善的比喻来说,以面向过程的方式来写一大堆函数,然后再分别塞到几个类里面,这就是Windows了。而Mac是真正的面向对象思想下设计的。

在Windows当中,我们貌似在操作一个“文档”、一段“文本”、一张“图片”,但实际上我们都不是在操作对象本身,而是类似于在操作handle——你不知道对象在哪里,你不能直接传递或操作对象,你只能借助仅有的API对handle进行操作,所有能对handle进行的操作都由API限制了。例如即使你在操作的是一张“图片”,你也很清楚那是一个存放为文件的图片,或者暂存在剪贴板的图片,总之你必须清楚handle在哪,否则你就算看到了那张图片也无法操作——图片在网站上,你先另存或者复制到剪贴板吧。

这种体验不就完全是面向过程的映射?每一个操作相当于调用一个或几个API。Windows发展了那么久,在人机交互方面还是脱离不了对DOS的简单封装。在这方面,Windows从前落后于Mac,现在还是这样。Mac虽然不能达到最理想的面向对象操作方式,但至少系统本身提供的体验要比Windows好,同时主流软件也比Windows的主流软件在体验上要好一个等次。

例如Skitch这个轻量级的图片处理软件,你可以抓起正在编辑的图片扔到桌面上,这就自动另存为一个图片文件了。文件与内存中的图片数据对用户来说已经无缝连接起来了。

再举一个例子,在Windows我们都知道回收站是个很好的比喻,不用的文件当然扔那里面。不过说真的,你多少次把文件扔里面了?你用得更多的是delete按钮,对吧?这是显然的,因为Windows用户习惯最大化窗口,这当然就把回收站遮住了,傻瓜才会选择在窗口里拖动文件的同时回到桌面接着再把文件扔到回收站里。Mac的回收站叫做废纸瘘,它出现在Dock上,Dock类似于Windows的任务栏,永远不会消失,就算自动隐藏也可以在鼠标靠近后自动跳出来,因此你永远可以把你看到的不想要的东西拖到废纸瘘上面去。

这也说明了一个问题,Microsoft这样去仿造Apple发明的交互方式是没用的,因为一点点的差异就可能导致可用性完全不同。Windows Mobile 7泄露的文档中,透露了Windows Mobile 7将可能有一些类似iPhone + Wiimote的功能,例如用手指拨动CD封面从而跳到下一张或上一张CD,甚至晃动手机从而跳到随机抽选的一张CD,这样的交互到底是否好用,真的很难说。

最后,无论你在开发Windows应用还是Web应用,我都建议你去弄个Mac来用一段时间吧,不要给一直以来Windows及Windows主流应用程序的交互设计方式禁锢了你的思路,你应该看一点新鲜点的东西。在以前,我认为Scriptaculous的拖放库完全是多余的,真该好像Atlas转变为ASP.NET AJAX时那样把拖放库丢一边,但在使用Mac之后,我才真正觉得在Web应用中推广拖放操作是非常有意义的。

假如我们都做一样的事情

之前写过关于Facebook News Feed的文章,现在开始反过头来思考trend的坏处了,那就是我们都变成克隆人了。

其实所有寻找同好的网站都有这样的问题,一开始你能够很好地寻找自己的同好,以及他们的爱好,在相邻的领域内拓展自己的爱好。然而实际上我们都明白这在数学上的意义,就是所谓的“类聚”,欧式距离相近的若干个点就聚唯一个类,并且一个点与这个类中各点距离的总和比与另外任何一个类中各点距离总和要小。

之后呢?因为你在变得越来越像你的同类,同时他们也变得越来越像你,这样一个类内的多样性就开始缩减,这绝对不是一件好事。有两种途径可以打破类聚,要么是创造类聚本身的网站致力于重新打破类聚,这听起来很好笑对吗?你的服务目的是创造类聚,但你又要打破它。然而另外一种途径就是,由外力来打破这种类聚,之后你的服务也就真正失去存在意义了,哪一种才是你所期待的?

我们都希望同类的人不停地聚集到自己的平台上来,但这是不可能的,在完全朝着目标的发展路线上一种可控的“叛离”是必须的。你希望聚拢一种用户,但无论是你喜欢还是不喜欢,中间总会带来一些变化,例如新的用户群体超过了原来的用户群体,最终超过临界成为了所谓的“变味”。需要一再强调的是,这种改变是不可避免的,你不能说控制你的平台不发展从而不改变用户群体,他们继续类聚下去也会爆发,因此我们需要在“可控”的前提下进行一些操作。

无论是之前的论坛“火了-水了-完了”,还是麦田现在所说的“有趣-无聊-暴力”,这都表明群体的进化是必然的,我们需要研究的不是如何保持一个群体以避免其发展。虽然上面两个例子看起来都是“衰亡”——总之就是越变越坏,但实际上这是一种发展。我们需要的是控制这种发展,而不是任其自然。

2008年1月8日星期二

跑去见Keso了

北京给我的印象很一般,不过没办法,中国的IT人都聚在这里了,甚至IT以外的人脉枢纽也在这里。与之对比,硅谷不仅仅有人,气候貌似是我喜欢的,生活条件也不错,而北京在“天时地利人和”这3个条件中就只有最后一个,却吸引那么多人跑来这里了,说明其人脉的优势是如此之强大以克服前两者的弱势。

今天晚上在布丁的带领下跑去见Keso等人,第一个印象是这些人特别能吹水,第二个印象是Keso对香烟的消耗率实在高。这样一群人,能够从互联网隐私问题扯到视频管理再到色戒,中间还间插着Google Camp与燕窝这样的东西,实在强。而且那种思维的跳跃性,让听众的大脑很快就会觉得超负载。

在奥校我已经习惯了和一群思维超级跳跃的人聊天,这没什么问题,不过那时候我们都是搞理科竞赛的,我们习惯以geek的思维来扩展,我们对用词与用意是否低俗并不介意。Keso这些人,art背景够强,不像我们只有science背景,于是说话总是喜欢挑些一针见血的,同时又保持言语的高雅性,这样非tech类话题我就很难插嘴了。

总体而言,去和Keso聊天还是很爽的一件事。下星期看看布丁又能带我去见些什么人。周围去找人聊天是一件非常有趣的事情,能认识到不同的人,了解他们的观点,因为这些人的背景都非常不同,所以视点可以是非常独特的。

2008年1月7日星期一

编写 iPhone Friendly 的 Web 应用程序 (Part 6 - iUI)

iUI是一个针对iPhone Safari的Web开发框架,由Joe Hewitt开发。这位Joe Hewitt曾经参与过Firefox的开发,包括其中的DOM Inspector以及Firebug,后来到了Facebook,为Facebook开发了iPhone专用版本,对iPhone Web开发社区算是作出了巨大贡献。

样式

我们继续说iUI这个框架。这个框架所做的事情,就是提供iPhone Friendly的交互方式与样式。为了简单起见,我们先来说说样式方面,iUI提供的不仅仅是一个CSS文件,基于这个CSS文件你所创建的页面能够符合iPhone的人机界面指引,并且看起来的效果贴近iPhone原生的应用程序,从而降低用户学习门槛,避免你自己设计的Web应用对iPhone操作不友善(例如按钮不够大,手指难以点击)。

交互

至于交互方面,iUI提供一个基于page的换页导航机制。这里所说的page不是一个Web页面,而是一个<body />内的顶级DOM元素,每一个这样的DOM元素都可以作为一个page,同一时间上仅显示一个page。页面上的所有链接,要么导致page转跳,要么导致整个页面转跳。这种转跳有如下几种情况。

转跳

如果链接的href指向的是一个锚点,例如#somePage,那么iUI就会在页面中寻找id="somePage"的page对象,然后进行转跳。

如果链接的href指向的是站内地址,例如/somePage.html,那么iUI就会使用AJAX的方法加载/somePage.html的内容并追加到<body />内,注意,/somePage.html必然是一个文档片段而不可能是完整的XHTML文档,否则把<html />追加到<body />下就是错误的了。追加的内容内可以有多个page,如果其中一个有selected="true"的属性,那么接下来将显示该page,否则显示追加内容中的第一个page。

最后一种情况是指向站内地址,但是有target="_replace"属性。iUI在看到target="_replace"属性后,就会知道该<a />所在的page内直属元素要被删除,并且替换为目标页面的内容。在这里用CSS来解释一下所谓的直属元素,body > ul#somePage > li > a[target="_replace"],这里<li />就是<ul id="somePage />的直属元素了。这种转跳通常用于曾亮加载,例如iPhone内置的Mail打开邮箱后自动加载50封邮件,点击more之后再加载50封,Web界面上就可以通过这种方式实现——一个<ul />内包含51个<li />,前面50个对应50封邮件,最后一个<li />包含<a target="_replace" />的more链接,目标页面就是下50封邮件的<li />

在转跳的时候,iUI提供了一种很好看的效果,你能够看到当前page从屏幕左边移出去,新的page从屏幕右边移进来,好像PowerPoint的某种幻灯片切换动画那样。如果添加了axis="y"属性,page还能够子底向下滚动。

历史记录

AJAX式的页内内容更新不是不好,问题就在于浏览器无法自动保存历史记录,导致前进后退按钮实效。iUI已经解决了这个问题,上述3种转跳中的前两种iUI都会自动创建新的hash以便创建历史记录,hash默认就是#_pageId的形式,如果当前显示的page没有id,那么hash就按照增量自动分配id。

在拥有历史记录之后,用户就可以通过浏览器的后退按钮向前翻页了,此时相当于加载前面的page,iUI知道这是一个后退操作,就会提供反向的滚动效果(自左向右或自上向下)。

如果我访问页面的顺序是A > B > C > D > B,那么历史记录会如何呢?历史记录会变成A > C > D > B,也就是说第一次访问B时B从历史记录中删除并重新添加到最前的位置了。

演示

说了那么多,我们来看看iUI的实战效果吧!又是Facebook或者Digg的iPhone版?不是,我们来看看自己利用iUI开发一个小应用的效果以及成本如何。就在上个周末,我花了不到20小时做了个名为iBaidu的小东西,自动抓取Baidu的搜索结果与排行榜并以iPhone friendly的方式显示出来。以下是发布到YouTube的演示视频:

服务器端使用的技术是Ruby on Rails以及ASP.NET。为什么需要ASP.NET?这是一个很郁闷的问题,因为Baidu是基于GBK的,而RoR的编码转换能力其若无比,我懒得花时间去寻找适合的转码库,因此直接拿了ASP.NET来做抓去代理,抓取的时候顺便做一下编码转换。如果不是编码问题,那么只需要RoR就能轻松完成任务。

小结

在这篇文章中,我们已经看到了如果使用RoR搭配Prototype,不好意思,iUI才对,要设计一个iPhone friendly的Web应用程序是多么地容易,开发过程也相当敏捷。如果你喜欢iPhone开发系列的文章,欢迎订阅:

2008年1月5日星期六

什么时候抛弃Live Messenger

最近全面通知QQ上的所有好友,包括群,说明我决定于2008年开始停用QQ或TM,需要继续保持联系的话就加我的Live Messenger或GTalk,无论什么事情,至少可以通过GMail联系我。我期望的是,如果你觉得我们之间的connection不那么重要,就不要来烦我了,我不关心你上线下线这样的琐碎事情,记录下我的GMail吧,没事不要在IM上找我,然而结果却是另一种情况。

在我在QQ上广播暂停使用QQ且给出Live Messenger与GTalk帐号后,一堆人来加我的Live Messenger。因为我在群里面广播了,有些人本来不是好友的,还变成了Live Messenger好友。可能我们在群上根本就没有直接对话过,这样就加进来真不知道说什么好了……我在Live Messenger上也不知道如何给他分类。可能有些人认为,只要有价值的人,也就先加了,避免日后要联系又找不到,然而其实他过去没有任何联系我的理由,将来可能也一直没有。

总之,我现在Live Messenger上面的好友数量暴涨,并且我也从Live Messenger换到Adium上来了,看不到以前的聊天记录了,因此如果我不记得你是谁了,那么请见谅。可能经过一段时间后,我又会选择停用Live Messenger,以过滤掉一批不用联系的人。

2008年1月3日星期四

想买个数位板

最近几天就在fancy这个东西,不知道什么时候才有米去买一个。感觉用笔来画画很爽,况且平时也能用笔操作,鼠标就省掉了,不会因为长期抓鼠标导致健康问题。

2007年12月31日星期一

新年新服务: MVP 播客上线

其实我很早就想做podcast(播客),10月份从三亚回来一直在筹备一个MVP博客,最终在前天完成了第0集(pilot episode)的录制,并将于今天稍晚时候上线。在整个过程中,我需要感谢dudu以及博客园对podcast提供的支持与服务,感谢BeanJeffrey对podcast准备工作与录制的投入。

首先,我介绍一下podcast为什么叫做podcast。过往,我们能够订阅feed,从而好像收取email那样收取网上的信息。例如,我订阅了ABC World New,设置了我的电脑每天早上7:00自动开机并打开feed reader下载feed,那么当我准备好早餐后,我就可以一边享受早餐,一边阅读新闻了,这和传统的喝早茶看早报没什么区别。

然而,ABC World New的新文章,附带了一个新闻视频片段,以龟速的下载速度,我可不能等下载完看完再去上班,因此我希望我的feed reader能够识别视频音频片段并且自动下载。RSS 2.0的<enclosure />标签是第一个出来把问题解决掉的,只要把这一个feed entry相关的文件放到<enclosure />链接内,feed reader就应该懂得自动去下载。之后,我把电脑自动开机时间改为早上5:00,预留两个小时,什么龟速也能把几分钟的视频片段拉下来吧。然后,我还是边喝着早茶(或者咖啡),边看新闻,不过这次不用读文字了,视频里面有人说给我听。

随后,iPod和iTunes又把这个应用提升到了一个全新的层次。如果你使用iTunes订阅新闻,起床后我只需要按一下同步按钮,视频音频都传到iPod上面去了,然后专心吃我的早餐,出门口时记得把iPod从同步底座上拔下来带走就是了。我在地铁或公交上有足够多的时间,把iPod拿出来看看或者听听头条新闻的时间是绝对是有的,甚至还能听听有声电子书。

由于这个功能在iTunes与iPod上就被命名为podcast,而且iPod在美国相当普及,所以大家就都叫podcast了。不过,Microsoft貌似避忌所有pod字开头的东西,以保持和Apple之间的距离,所以就坚持把同样的东西叫做netcast,这样显得中立一些。不过Zune2里面的功能菜单就写着podcast,看来负责整理Zune2菜单字符串资源的人有被炒鱿鱼的危险了……另外,国内有一些名为播客的东西其实不是播客,土豆一开始就给人如此批评了——不支持RSS订阅,也不允许下载,更别说放到iPod上了,这也想带上播客的头衔?

好吧,对podcast的介绍到此结束,稍后MVP博客的第0集将会发布到netcast.cnblogs.com,并且我还会另外发贴详细说明如何订阅podcast。敬请期待!

2007年12月30日星期日

我嘅 2007

(以下的是实验性文章,全文使用Cantonese书写而成,附带Mandarin翻译,请将鼠标移至带有下划线的短语上以查看翻译。)

點解成個博客園都喺度“我2007”,仲要大部分都差唔多……好,我就寫唔同,例如……人脈啦。我要,技術唔係最重要唔係管理,而係人脈。

2007年,個人發展上兩個重要事件,一攞咗微軟MVP,二B家,兩樣都要靠人脈(要多謝人自然非常多)。,第一你要認識人際網絡中充當關鍵節點個人,第二個人要睇得起你。簡單,如果你有能力,無論係技術定係管理,首先你要識得渠道(或者叫中間商),其次要覺得你超值,先有機會賣得出去,而且賣個好價錢。渠道前提下,大家都明白廠家直接向客戶銷售成本有幾高,你一個人能夠聯係買家數量就非常有限

如果一開始,我唔係Dflying同埋Jeffreyblog上評論,佢哋唔會blog,亦就唔會佢哋鼓勵我將文章發到首頁,咁嘅話,可能dudu亦就唔會知道我存在,dudu推薦我去MVP就知從何談起。所以,MVP呢件事一定要多謝Dflying、Jeffrey同埋dudu。當然,仲要多謝所有讀者,特別有留言嗰啲,因爲有留言自然激發思考。

然而,MVP並唔係終點,只係另一個起點。之後,有中國MVP峰會,Bean介紹我唔少微軟同埋其他MVP,先有后嚟一啲合作項目,例如netcast啦。所以,認人有得做,因爲好多係呢度,我要多謝Bean、Jeffrey、dudu,特別dudu,完全講求回報支持我哋做netcast。

另外一件事,就關於賣身㗎嘞,我意思搵工。寫“我2007”入邊多人寫自己今年畢業搵工如何如何,我又可以寫啊。搵實習事就,全職申咗好幾間有噃咁上吓大嘅IT公司,包括BGM,其中B家G家過人做推薦(多謝布丁同埋Junyu)。B家最早offer,所以就賣B家算嘞G家M家申請算“無疾而終”(拒信,hold咗喺唔知邊個環節)。但係,我想唔係點樣賣畀大公司而係推薦有重要

如果人推薦,你簡歷可能石沉大海都話畀你知,而且石沉大海概率仲唔細添但係,有人推薦嘅話,你就清楚流程,其中每個環節對你評價如何都透明一啲你就可以不斷調整自己。推薦人熟悉公司内各個職位差別嘅話,對你選擇職位亦有幫助,好似高考選專業蠱蠱吓唔好啦。(如果你高考嗰時已經識得師兄問清楚專業你可以跳過。)

當然,最重要嘅係推薦你個人真係認爲你值得擁有呢個職位,而唔係應付你。積極幫你,就反映一點,影響推薦效力。唔好以爲幫你ERP或者HR之類系統填落力幫你件事,幫你同你面試官溝通你情況,你成數就越大。如果你搵到個人只係礙于人情而推薦你,根本覺得你將來成爲同事嘅話公司都有好處,你得到好處無非就係免筆試,對促進你公司之間互相了解一啲作用都

免筆試……免筆試又有用呢?其實筆試過後離offer仲有十萬八千里遠。聼講G家美國本來就筆試,只係中國應屆畢業生實在太多就筆一筆,篩一篩。有時甚至筆嘞,咁樣推薦推薦都係一面起步,你希望你優勢更好傳達面試官嘅話除咗面試時候表現要好,就靠推薦人溝通

最後,通過一個故事結束本文。曾經,Mary總係好有激情同人同埋新公司,其中一個聽衆就係Unity Way董事會成員:John Opel。五年之後,John Opel,亦就係IBM董事長,要為IBM機器一個操作系統。邊度?去WashingtonRedmond會見Mary即係Bill Gates。多謝同埋IBM單生意,Bill Gates做首富。如果John Opel從嚟聽講嘅話,IBM絕對唔會派人去Redmond一間當時幾乎Microsoft一樣默默無聞公司。

點樣放電

將件衫,特別係羽絨,剝落嚟,然後隨便搵嚿金屬物掂吓,咁就會放電嘞!喺北京D咁乾燥嘅地方,隨時都有可能無啦啦畀電親,真係抵死。不過我今日要講嘅放電唔係呢种放電……我要講嘅係attractive呢种放電。

要放電,首先要有電壓,亦就係一D你有佢冇嘅嘢。例如話,錢啦。又或者係一D更加虛無嘅嘢,所謂嘅demonstrate higher value就係無中生有搞D咁嘅嘢出嚟嘞。例如,你只係一般醒,但係扮到鬼咁叻鬼咁競,又搞到人哋信以爲真喔,你就搞咗個高電壓出嚟啦,如果人哋又過電,咁就掂晒嘞。

其中最重要嘅就係佢要信,咁先過電,於是你放出嚟嘅嘢就一定要係佢理解能力之内嘅嘢,而且最好係佢明知冇但又無能爲力嘅嘢。最好就係佢好希望自己能夠擁有嘅,咁既然佢得唔到,就當然希望從你身上得到啦。事實就係咁簡單。

2007年12月28日星期五

编写 iPhone Friendly 的 Web 应用程序 (Part 5 - 交互入门)

我们已经研究过XHTML和CSS了,现在开始看看最后一部分,也就是JavaScript,以及它所提供的交互能力。

无AJAX交互

第一种我们要看的交互,是完全不使用JavaScript,这其中一个例子就是GMail。GMail的iPhone版其实就是由普通的GMail移动版修改过来的,界面上更贴近桌面版GMail了,然而交互性并没有怎么提高,每一个点击都对应一次刷新,没有任何AJAX可言。

事实上,不用任何AJAX效果并不会让你的iPhone Web App低人一等,如果有人讥笑你的应用没有引入任何AJAX功能,你可以直接跟他说“GMail也没有”。因此,如果你在开发的过程中决定不把任何时间投入到AJAX相关技术的研究,这是没问题的,确保你的服务器响应速度,并且交互设计得当,那就行了。

以服务器端为中心的AJAX

接下来我们看看另外一些应用,例如之前说到的几个,就拿最简单的AppMarks来说说吧。首先,使用User Agent Switch更改你的Firefox的user-agent属性,伪装为iPhone,然后打开AppMarks,并且打开Firebug。接着点Menu -> Add -> Browse,看到出现AJAX请求了吧?猜猜这个请求是什么类型的,面向内容(传输更新上去的XHTML)、面向脚本(传输进行更新操作的JavaScript)还是面向数据(传输更新相关的JSON)?答案是——面向内容的!

这可是Web App哦,不是一般带有一点点AJAX的网页哦,我们要MVC,我们要“先进”的面向数据,为什么要“落后”的面向内容呢?至今为止,我们能够看到的大部分iPhone Web Apps,都将MVC保留在服务器端了,客户端唯一需要知道的就是内容更新,不存在任何的客户端MVC模型。暂时我还没看到有面向脚本或者面向数据的,如果你见到有应用这样做了,请告诉我。

我们继续说MVC的事情。现在大多应用的设计方式是这样的:每一个应拥有一个view framework,然后每一次点击所作的操作就是切换view。例如刚才说到的AppMarks,从Menu进入Add是一个view切换,不过因为Add这个view的内容是固定的,因此一早就包含在页面里,不用AJAX请求直接加载就行了。另外一种情况,就是好像加载Browse那样,是需要AJAX把view请求过来才能加载的。除了切换view,我们还需要action,例如提交数据就一定需要action的。说到这里,感觉是不是和RoR或者类似框架扯上关系了?事实上,RoR,或者类似框架,确实很适合用来做iPhone Web Apps。

以客户端为中心的AJAX

那么除了RoR,我们还有别的选择吗?我们可以选择使用一些客户端框架来实现类似的效果。这样说吧,类似RoR那样每一个view都是一个模板,但不是rhtml,而是普通的html,没有复杂逻辑,点击连接后不是由RoR引擎调在服务器端用rhtml,而是客户端自己直接拦截了链接点击并用AJAX的方法去请求该html然后更新内容。这样一个框架,可以在Wrox的Professional iPhone and iPod touch Programming : Building Applications for Mobile Safari一书中见到。这本书写着2008年1月出版,但实际上已经出版,并且可以下载源代码。我暂时还没办法买到这本书,但源代码中就包括了这样一个客户端框架。

然而,这种以客户端为中心的做法并没有真正在客户端引入一个MVC,它只是简单地把服务器端的MVC裁减掉了,服务器端只能简单的发送内容或响应提交,因此只适用于比上面的以服务器端为中心的模型更简单的情景。如果你正在编写的应用不涉及大量的提交操作,或者根本就是Web1.0网站,我的意思是,单向传递信息不接受任何用户提交的网站,那么这种轻量级的模型就非常适用了。

小结

在这次的文章里,我们介绍了三种常见的iPhone Web Apps交互方案,没有哪一个是绝对更好或者更坏的,按照你当前开发的应用做出选择吧。将来我们写文章深入探讨其中的一些实现细节,或者是交互模式,但前提是我先完成了几个iPhone Web Apps。欢迎订阅本系列文章:

2007年12月26日星期三

编写 iPhone Friendly 的 Web 应用程序 (Part 4 - CSS)

说到编写CSS,大家的第一反应肯定是——有没有选择性CSS。有!我们可以设计一个CSS,使得只有iPhone上的Safari会采用它,其他浏览器都会无视它,这样我们就可能可以复用现有的XHTML页面代码,仅仅为它们引入新的CSS就能够适用于iPhone,无须重新编写页面。这个选择性CSS链接语句如下:

<link media="only screen and (max-device-width: 480px)" href="small-device.css" type= "text/css" rel="stylesheet" />

Safari是支持media选择的,only screen声明该CSS仅用于屏幕显示(不用于打印),同时Safari还支持max-device-width这样的选项,限定屏幕宽度小于480的设备才采用该样式表,这就把iPhone与桌面浏览器划分开来了。

另一个做法是在服务器端就判断当前浏览器是否是iPhone上的Safari,从而选择返回哪个CSS文件,这可以通过user-agent进行判断,iPhone的如下:

Mozilla/5.0 (iPhone; U; CPU like Mac OS X; en) AppleWebKit/420+ (KHTML, like Gecko) Version/3.0 Mobile/1A543 Safari/419.3

判断了浏览器之后,就可以开始针对Safari编写CSS了。Safari比较爽的一点是对CSS3的支持,设计PC端网页时总是要兼顾那个“后进”的IE,从而避免使用CSS3,或者需要确保IE在无视CSS3规则后仍然正确显示,现在不用为此而头痛啦,只要是Safari支持的就能用,针对一个浏览器设计就是比针对一堆浏览器设计要爽!

CSS3

接下来我们就列举一下Safari支持的CSS3属性吧:

边框

背景

色彩

  • HSL - HSL色彩
  • HSLA - 带Alpha通道的HSL色彩
  • opacity - 透明度
  • RGBA - 带Alpha通道的RGB色彩

文本特效

用户界面

  • -webkit-box-sizing - 可以让盒模型变得基于边框而非内容
  • resize - 让用户可以更改盒的大小(iPhone上不支持)
  • outline - 设置盒的外边框

选择器

Safari支持大部分的CSS3选择器,你可以自己使用桌面端或iPhone上的Safari打开CSS Selectors Test进行测试,桌面端与iPhone上的Safari测试结果是一致的。Safari完全通过测试的CSS3选择器包括:

*, E, .class, #id, E F, E > F, E + F, E[attribute], :link, :visited, :before, ::before, :after, ::after, :first-letter, ::first-letter, :first-line, ::first-line, E - F, :root, :not(), :target, :enabled, :disabled, :checked

其它

  • media - 根据media选择性加载CSS
  • multi-column - 内容分栏支持(iPhone上不支持)

还有一些Safari自己做的CSS扩展没有列举出来。Safari完整的CSS属性支持列表请看这里:Supported CSS Properties

表单

Safari支持对<input />元素比较高自由度的CSS定义,例如这样的:

实现所需的CSS属性上面已经列举了,所以不再详细说明,灵活运用就是了。值得注意的是,某些<input />的默认背景并非纯白色的,而是半透明的,这使得这些元素能够更好地和不同的背景颜色进行颜色混合。为了说明这一点,请先看白色背景下的示例:

然后再看看蓝色背景下的:

小结

CSS相关的话题也说完了,很简单是不是?大部分针对桌面浏览器进行符合Web Standards页面设计的设计师都能轻易掌握这部分内容,然而这只是实现设计的手段,到底如何设计一个界面,在iPhone上才算是拥有高度易用性的,这才是真正的问题。这个问题我们将在以后探讨,至少现在你能够将你自己的设计在iPhone上准确无误的实现出来了,那么我们下一步就进入JavaScript的讨论环节了。

本iPhone Friendly专题的订阅地址如下:

编写 iPhone Friendly 的 Web 应用程序 (Part 3 - XHTML)

在接下来的两篇文章中,我们将探讨iPhone上的Safari所支持的XHTML与CSS,之后才进入JavaScript的讨论。作为一款现代化的浏览器,Safari当然是基于标准的,那就让我们看看Safari支持哪些标准吧:

  • HTML 4.01
  • XHTML 1.0
  • CSS 2.1 以及部分 CSS 3
  • JavaScript (ES3)
  • DOM (Level 2)
  • AJAX (XMLHttpRequest)

熟悉这些标准并且平常也坚持Web Standards实践的朋友估计要笑出来了——就这些吗?我们天天在用啊,还有必要专门写文章来说明吗?事实上,Safari之前作为一款无PC版的浏览器,一直用户数量就不高,因此对它的研究也就不多,然而Safari其实有不少自己的扩展,因此还是很值得研究的。既然我们是针对iPhone设置,其实就是针对Safari设计,无需考虑兼容其它浏览器,这时候为什么不好好利用这些扩展增强自己的应用程序的可用性呢?

好吧,不说废话了,进入Safari对XHTML支持的介绍吧!

链接

iPhone对一下这样一些链接有特殊支持:

邮件

传统的mailto:地址iPhone将能自动使用内含的邮件程序处理,直接进入编写邮件的界面。完整的mailto:格式请参考RFC 2368

电话

iPhone上的Safari会自动对看起来像是电话号码的数字串(包括已经加入连字符或括号格式化过的)添加电话链接,点击之后会询问用户是否想要拨打该号码。如果你不希望开启这个自动识别,可以将它关闭:

<meta name="format-detection" content="telephone=no" />

如果你关闭自动识别后,又希望某些电话号码能够链接到iPhone的拨号功能,那么可以通过这样来声明电话链接:

<a href="tel:13800138000">13800138000</a>

Google Maps

Google Maps的地图链接会自动调用内置的Google Maps客户端软件打开,而非在浏览器内浏览。链接可以是一个地点查询:

<a href="http://maps.google.com/maps?q=cupertino">Cupertino</a>

也可以是一个路线查询:

<a href="http://maps.google.com/maps?daddr=San+Francisco,+CA&saddr=cupertino">Directions</a>

YouTube

如果链接是指向YouTube视频地址的,将会自动调用内置的YouTube客户端打开播放。能够识别的YouTube地址格式为:

http://www.youtube.com/watch?v=<video identifier>

http://www.youtube.com/v/<video identifier>

其中<video identifier>替换为视频的id。

图片

由于用户浏览时有可能使用Wi-Fi,也有可能使用EDGE(GPRS),因此你必须优化你的图片以确保即使是在使用EDGE访问你的网站的用户也能流畅的打开页面。因此你必须优化页面上的图片,尽量减少它们占用的传输带宽。另外Safari本身还对图片有如下的限制:

  • GIF(包括GIF动画)、PNG与TIFF解压后的体积小于2m。意思是,原图的长度乘以宽度再乘以每一个像素的位数,得出来的大小要小于2m。
  • JPEG解压后最大的体积是32m。解压体积大于2m的JPG会被进行二次抽样,最终显示给用户的是二次抽样后的结果。这使得Safari能够显示数码相机直接拍摄出来的照片,但显示时实际上是降低了精度的,以提高程序的执行效率。

为了尽量提高效率,例如你要将100*100的图片显示为10*10,就要在服务器端执行压缩操作,而不要直接用10*10的<img />来引用100*100的原始图片。

表单

text, password, textarea

在设计文本框的时候,必须记住用户点击后会出现软键盘,这时候可视区域就减少了:

另外在文本框中输入时,iPhone提供了自动大写与自动更正两项功能。自动大写的意思是,在输入开始的时候,以及在一个句号并空一个格后,自动会启用shift,输入一个字母后该shift自动消失。自动修正的意思是,iPhone会自动根据词库,包括自带的以及从你过往输入分析而来的,来对你的输入进行自动更正。我们都知道用手指点击那么小一个软键盘很容易误按旁边的键,这时候你可以不用忙于修正,只要iPhone提示的自动修正的词正是你想要的,你就可以按空格然后输入下一个词,iPhone会自动修正前面那个词。

要关闭这两项功能,可以通过autocapitalizeautocorrect这两个选项:

<input type="text" autocapitalize="off" autocorrect="off" />

select

必须留意到的是,iPhone上的<select />以不同的方式显示,以便于用户操作:

upload

iPhone不支持任何的文件上传下载,因此<input type="upload" />总是会显示出来,并且是……disabled的!

多媒体内容

iPhone上支持显示的多媒体内容,除了图片还包括QuickTime音频视频以及PDF。

如果需要创建视频,可以使用QuickTime Pro。如果你正在使用一台MacBook或者iMac,并且已经将QuickTime升级为QuickTime Pro,可以马上就试一试!你需要做的就是打开QuickTime Pro,然后开始录像,(接着请对着镜头傻笑3秒,或者做点别的),最后选择"Export for Web"。其中iPhone格式与iPhone (cellular)格式分别适用于Wi-Fi与EDGE环境,iPhone在播放时会自动根据当前的环境选择适合的流媒体文件进行下载与播放,另外poster是指影片播放之前在页面上显示的那一帧静态图片。导出后文件夹里ReadMe.html说明了如何将这些文件添加到XHTML中。

(事实上,导出结果中QuickTime控件引用的那个mov文件不包含任何视频数据,它只是一个引用,类似我们编程时所说的引用,用于指向真正的视频文件。不过这个引用指向的是多个视频文件,客户端根据当前的状态自动选择正确的视频文件来播放。)

其他琐事

虽然说是琐事,但也必须注意到,这样才能让你的页面更好地受到Safari的支持。这包括:

  • 声明正确的doctype
  • 避免使用frameset
  • 每一个独立的资源文件,HTML、CSS、JavaScript、以及非流媒体的其他多媒体文件,限制在10m之内
  • 顶级入口的JavaScript执行时间限制为5秒,超时将自动终止。
  • JavaScript分配内存上限为10m。
  • 同一时间最多在Safari内打开8个子窗口(同时浏览的页面)。

小结

XHTML部分到这里就讲完了,可以看出iPhone对XHTML的支持与桌面端的Safari是类似的,只是加入了更多扩展功能而已。下一期将开始讲CSS,欢迎订阅: