标题来自先生的一句话:生不枉来,死不犹豫;立志天下,魂归大地。我似懂非懂。
前些日子,COS内部说起个人网站的事情,我这两天抽空琢磨了一下,猛然间意识到我在折腾网站的八年里走了个循环。昨天我在邮件中描述为“回归尘土”,这事情是这样:九年前开始正式接触电脑,一年后我开始对网站感兴趣,并且找免费个人主页空间找了很久,直到后来有一次在一张传单中看见一个可以免费建站的广告,于是就注册建了一个,当然,那时候不会有什么好货,域名是三级域名,我呆头呆脑抄了很多所谓的英文美文在上面,还从图书馆借了书学HTML,连VBScript都仔细学过,而且对于写个在网页内弹个对话框的小脚本乐此不疲。为了说明这个乐此不疲有多乐此不疲,举一例:在机房上数据库的课,老师会把所有人的屏幕都控制住,而我发现其实只有显示器被控制住了,键盘鼠标仍然可以在“幕后”操作,因此,我按Win + R快捷键,盲打输入notepad,回车,然后开始盲打写弹对话框的VBSript,等到下课,屏幕被解放,我写的脚本真的可以运行并弹对话框。那个免费个人网站也让我学习了一点CSS的概念,但我主要还是用Word的思维方式做网页,哪里要加粗就直接加粗,哪里要变红就选红色,几乎没有“内容与样式分离”的概念(拜Word所赐,可能大多数人到现在也没有这个概念);话说回来,其实我还真用过Word做网页,我的一个亲戚当年让我帮忙做几个网页,我就是手工敲进Word,然后另存为HTML。再过一年,系里网站工作室招学生维护系里的网站,我就呆头呆脑报名去了,就凭我那Word式网站功底。之后接触了Dreamweaver,才算真正掌握HTML,并接触ASP和JavaScript,并且尝试过从零开始建Access数据库连ASP,所以IIS也熟了(估计很多人也不知道什么是IIS,这样也好,祝愿Windows服务器早日垮台)。DW中学会了模板的概念,网页的头尾都用模板定义,这样就省去了重复劳动。因为DW和Fireworks是同一个公司出品,所以编辑图形我都用Fireworks,这也是我在R包忍者篇中说我曾经想学Photoshop的后台故事。从接手系里的网站开始,我开始捣腾论坛系统,此乃灌水元年,也是统计之都的前世。论坛系统换过两次,一直折腾到那台老旧的IBM服务器彻底瘫痪掉。再过一年,博客这个概念开始在中国发芽,第一个博客网大概就是方兴东的博客中国,后已改名为bokee,当时那个玩了两年10磅宋体字的我,看见这个网站有一个12号字的主题,于是立刻注册了个帐号,开始写博客。我对CSS的了解,自此开始深入,比如我曾经发现通过CSS来隐藏网站上的广告的办法——谁让他们支持自定义CSS的呢,我定义一个display:none就把网站上的广告灭了。年少轻狂的这个娃儿,整天给客服提意见,说这不灵活那不好,有一天方兴东接见了一批用户,客服叫了我去,于是我骑着破自行车颠儿颠儿去了,这就是无知者无畏。今天我再搜了一下当年的历史,后知后觉发现本小子也曾经和张纪中、方舟子同时出现过“名人大话博客节”里,现在顿时觉得脸上贴了不少金,哥也曾经风光过。那时候是钱江晚报的记者打电话采访,我都忘了我说了些什么了。在博客中国写了两年,觉得系统越来越差,于是换到blog.com.cn写,它比较容易自定义,当然,对“久经沙场”的我来说,首先就是要用CSS把页面上的广告灭掉。再折腾两年,系统控制越来越严格,尤其是关键词屏蔽,最可恨的是你写一篇文章提交发现不让提交,但就是不告诉你哪个词犯法了,只能一边在心里骂狗日的一边从最后一句话删起,删一句提交一次,看哪次能通过,再一句一句加回来,这就是我早期培养的程序debug方法,极其白痴,极其有效。再后来,换到MSN Space,因为英文字体看起来舒服,所以开始写英文博客(看,从始至终,我都是个视觉驱动的动物,各种转变的原因听起来都非常脑残)。从英文博客开始,我变得极其注重HTML代码的干净(经常切换到代码界面下看看代码是否整齐),或称为HTML代码洁癖,无法容忍没理由的加粗变红或更恶劣的放大字号,这也是我把COS论坛从PHPWind改为bbPress的理由之一:我不能容忍发贴者能放大字号或使用楷体隶书。英文博客写了两年,后来大家都知道了,大中华局域网来了,自此本小子开始建真正的个人网站,注册个人域名,买服务器空间。PHP+MySQL在搭论坛和建个人网站期间也被迫学了点皮毛。后见Wordpress,深感设计之惊艳——无论是PHP程序还是外观,于是COS的主站从MePHP换到WP。无论什么系统,我已经脱离了刀耕火种的纯手工HTML生活。到如今,我在GitHub上写了两年代码后,猛然意识到Markdown这门语言之精炼,这正是我追求的(极度)简洁,而GH对Markdown和其它伪标记语言都支持得非常好,而前两天,又发现基于Markdown的Jekyll,纯文本写博客的系统。除了R语言别的都不会的本小子,意识到我对Ruby、RubyGems和Python的认识已经落后于时代若干年,我以为整个世界还是在PHP+MySQL中运转,结果这些语言已经派生了无数惊人的美观的简洁的静态网站系统。从最初的静态网页,到现在再回归静态网页,我走完一个了循环。回想这些陈年旧事,不免让我再思考乔布斯大人,关于他的报道,我大概就认真看过一两篇,头一次知道他是佛教徒,世人总喜欢盖棺论定,尤其爱总结已成功人士成功的原因,就像经济学家在过去的五次经济危机中成功预测对了二十次一样;我想知道他到底在想什么,他如何追求能降伏用户的细节,或者说如何让产品始终带着人性。统计之都的口号“专业、人本、正直”或许是个好的口号。
如果网页可以如此简洁高效并且只是基于纯文本,那么我可以立刻嗅出统计人的一个光明前途。此处省略八千字,如果你手中有八百万风投,请两年后联系我。这里我要说的是魂归大地,但并不是要说我自己,网页和魂归大地扯上关系有点勉强,这些东西真刀实枪干活就行了,没必要整得那么玄乎。最近有两个TED视频,我觉得都非常好,让我想起先生的“魂归大地”。一则为开发新(纳米)材料获取能源(太阳能)的人,技术听起来很诱人,你家的窗户玻璃在夏天自动排热、冬天吸热,不知道能省多少能源,但这不是关键,关键是视频的最后,他从钱包里拿出一张旧报纸上剪下来的照片,那就是那幅著名的获普利策奖的照片《饥饿的苏丹》。“她不应该死于缺水,无论如何”,演讲者说。
另一则为赤脚运动的印度大爷,博士毕业,回村,跟老娘说要先挖井五年(如果我没听错的话),老娘听了差点没气疯。一辈子干了一件事,教育印度农民(或者说被教育),尤其是印度农妇,让五十多岁的老大娘都学会了整太阳能照明;这大爷认为民间自有高手在,要发掘他们的天才才干,向他们学习,他的学校里学生是老师,老师是学生;妇女们都会用太阳光聚焦了做饭,一个个比工程师都厉害;一位妻子说有了太阳能照明,她头一次在冬天里看清了她丈夫的脸。本小子非常相信这位大爷对贫民的看法,穷人有穷人的生存智慧。某个偏远山村的夜里头一次亮起灯光,这种感觉可能就是魂归大地了吧。
前些日子有位童鞋在R-help邮件列表里问如何生成那种单词大小与其出现频率成比例的图,这玩意儿也就是通常所说的标签云(Tag Cloud)。我琢磨了一下WordPress的插件wp-cumulus,发现其原理很简单,不过就是将标签信息以XML形式通过JavaScript传递给一个Flash文件,所以也很容易用R去实现这个传递过程,即:将文本、超级链接以及频数写成XML,然后嵌入到HTML文件中。整个过程参见Creating Tag Cloud Using R and Flash / JavaScript (SWFObject)这篇日志,函数源代码和示例数据都可以从那里下载。
效果是这样的:
(通过RSS阅读的童鞋们请打开原文链接在浏览器中观看,否则啥都看不到)
对这个话题关心的客官应该在网上看到过不少老外在他们的主页上强烈声明他们能接受的邮件格式,其中最广泛的一点可能就是关于HTML格式的邮件。很多人都反对或讨厌接受HTML格式的邮件,而仅仅接受纯文本格式的邮件,原因洋洋洒洒可以有几十条。如果你有足够的耐心,你不妨读一读这个页面。
另一点就是MS Word附件,这也是他们非常反对的。关于这一点,当然属自由软件战士Richard Stallman在GNU网站上的声明最有名了。
本人没有耐心去阅读上述页面,但我非常同意这两点。HTML邮件纯粹是浪费空间,接收者只需要看邮件的文本即可,发送者不用自己加粗或放大字体,更有甚者如网易邮箱还使用信纸,这所有的工作对于你的接收者来说可能都是白费:他们的计算机和你的可能大不一样,你发过去的带格式的邮件在他们那里也许变形得没法看了,所以一般还是发纯文本邮件吧。MS Word也有同样的考虑:你的接收者未必使用Windows系统或者安装了Office的某个版本,换言之,MS Word不是跨平台通用的文档格式(不幸的是很多人都被微软洗脑了),因此对于发送的附件来说,要尽量考虑对方是否能够打开,例如PDF格式就是跨平台通用的,而且版本的影响很小(这一点要强烈谴责MS Office 2007!)。
使用Web界面收发邮件的用户可以设置邮箱使用纯文本格式发邮件,使用客户端的同样也可以设置软件切换为纯文本格式。
今天又遇到一例Word发过来打不开的情形,于是操起键盘写下如上两点注意事项。尤其是那些跟老外发邮件的同志们,切记要注意。另有一点,最好不要给洋鬼子看“雅虎邮箱,您的终生邮箱!”之类的签名。
为了MSIE能利用自身的缓存,真是让我想破了头。好在到现在终于找到了一种解决办法,其实所有的技巧都在于:不要用JavaScript调用任何与URL有关的对象。既然不能用JavaScript动态改变页面内元素(比如图形<img src=… />)的URL,那么,想要在页面内动态且快速显示图片的路基本上只剩下一条了,那就是CSS。基本原理是:利用JavaScript动态改变一个层(<div id=…></div>)的CSS属性,若想让它显示,则设置为*.style.display = “block“;否则,设置为*.style.display = “none“。通过对若干个层的依次显隐,一副动画就大功告成了。
当然,Firefox对这种办法也是支持的。至此,我才基本搞定了动画在网页上的显示方式——万里长征的第一步。
今天看JavaScript Reference顺便也了解到window.onload的作用,当一个页面在客户端加载完成之后这个函数就会被调用,因此可以事先在页面内放置一个“正在加载”的说明字样,等页面全都加载完毕了之后把这个说明隐去,并将动画的“开始”按钮设置为可用(disabled = false)。这样一个动画页面就完美了,吼吼。
依然参见:http://r.yihui.name/misc/java.htm(猛增速度,faster,直接把时间间隔减小到0秒,看看是什么效果)
在此之前,我走的弯路太多了,现在综合起来也就一个特点:那些方法全都涉及到URL……
- 比如设置图片的src属性(*.src = …)
- 比如设置表格的背景(*.setAttribute(“background”, …))
- 比如设置对象的背景图像(*.style.backgroundImage = “url(…)”)
- 比如把一个对象的HTML代码(包含图片标签)赋给另一个对象(*.innerHTML = **.innerHTML)
- 等等
而对一个对象的显隐控制不会涉及到图片地址,只是单纯的显示或隐藏一个对象——实质上它一直都在这个页面里。
昨天半夜被一个JavaScript的问题迷惑了好一阵子,然后才反应过来,这又是IE和Firefox的差别。主要问题是,Firefox对 document.all["id"] 这种获取页面内元素的方式并不太支持,而最好通过 document.getElementById(“id”) 这种更严格的方式来引用页面内的对象;对于IE而言,两种方式都可以。
之所以涉及到这个问题是因为我想在HTML页面中直接实现动画展示,省得还要费尽苦心去研究GIF文件格式然后读写GIF文件以便生成GIF动画文件,通过JavaScript的方式生成动画比研究GIF要容易多了,只需要调用Java脚本改变一幅图的src属性就足够了,然后用一个循环让图像“动”起来。示例参见:http://r.yihui.name/misc/java.htm页面底部(点击按钮观看布朗运动)
这两个网站是我所看到比较经典的JS图片放大效果网站:
前者是在页面内缩放,后者是采用的“全屏”效果,我看后者的代码稍微简单一些,就采用了后者,不过也借鉴了前者的一个放大镜图标,这样有助于提醒访问者他所看到的这幅图片时可以继续放大的;不过这个图标还费了我半天劲才让它在IE中也显示出来,主要是IE对CSS中文件路径的解析比较奇怪,而Firefox就能正确解析出来。
那么以后本站中的图片就可以有缩放效果啦!而且对于多幅图片,还可以以幻灯方式依次浏览,嗯,8错8错。
做网页时比较头疼的事情之一就是要不停地考虑兼容问题:一方面考虑不同的分辨率下的效果(1024*768、1280*1024等),另一方面就是浏览器的兼容(Internet Exporer、Mozilla Firefox等)。在我做网站的初期,我比较重视前者,因此做网页时经常换分辨率,那时候还特别重视800*600的分辨率,如今觉得这种小显示器可能已经只是少数了吧,因此还是以1024*768为中心设计网页的宽度(980px左右),保证在1024*768下面把屏幕基本填满,而在1280*1024下面看着也不觉得太窄就行;后来开始用Firefox时,发现IE和Firefox对HTML的解析有很多区别,因此开始琢磨浏览器的兼容问题。
昨天花了好半天时间把这个Blog的模板自己重新改写了一遍,这个过程中曾经对层(div)的对齐问题恼火了一阵子,因为设置body的文本对齐为居中之后,里面的div在Firefox下死活都不肯居中对齐,后来才明白,必须得设置div的左右边距为auto才行。总体感觉Firefox对HTML的解析还是好一些,比如本页右边的那些方框中的列表项我都设置了强制不换行(white-space: nowrap;)、隐藏多余的部分(overflow: hidden;),可是当鼠标移上去的时候,IE就会把多余的部分又给显示出来,而Firefox就不会。这一点我想了半天都没找出好办法解决,于是就那样扔着吧,不管了。
其实这次改模板的主要目的是想应用<fieldset>和<legend>这两个标签,顺便把灰色的背景改为白色、把引用<blockquote>和代码<pre>的样式重新设置一下。一段时间之前我曾经看到过一个叫Planet PHP的国外Blog站,当时特别喜欢它那种像Visual Basic里面Frame控件的格式,也就是这样的:
While FIELDSET is not supported by old browsers, it can be used safely by explicitly closing any preceding P element with </P> or by including an empty P prior to the FIELDSET. This causes non-supporting browsers to infer the start of a block-level element even though they ignore the block-level FIELDSET element.
The content of a FIELDSET element must begin with a LEGEND to provide a caption for the group of controls. Following the LEGEND, FIELDSET may contain any inline or block-level element, including another FIELDSET.
因此看了看它的网页源码,发现用的是<fieldset>和<legend>标签,本来之前觉得挺神奇,还以为是用CSS+表格作出来的,看了源码才知道原来这么简单。于是乎,我这个Blog页面也就改造成这样了。
关于引用和代码的样式,其中“引用”采用了一个“引号”的图片作为背景放在左上位置,而“代码”采用了上下两条水平虚线作为分界标志,这两种样式的字号都缩小为11px,不过在IE下面看不出11px和12px汉字的区别,但在Firefox下英汉的11px字号都确实被缩小了。
虽说HTML语言简单,而且理论上用cat()函数就足够写文件用了,但我觉得Eric Lecoutre写的这个R2HTML包还是很有价值的,轻轻松松就可以获得漂亮的网页输出。
主要函数:
- HTML():这是个泛型函数(generic function),会根据传入参数的类型(class)自动生成相应的HTML代码。
- HTMLbr():熟悉HTML的人一看就知道,这是换行符”<br>”。
- HTMLhr():同上,这是水平线”<hr>”。
- HTMLInsertGraph():顾名思义,这是插入图片,即”<img src=… >”。
其实比较好玩的是即时生成HTML的两个函数:
- HTMLStart()
- HTMLStop()
它们会记录你在R中的一系列操作,最后用框架页的形式给出类似于日志(log)的报告。


近期评论