Chen Yangjian's Blog

Carpe diem - Seize the day

正月里去厦门(一)

| Comments

正月里,走亲访友之余,我与妹纸去了厦门。要去那是老早就定了的。有段时间,宅在家里,只能让思想在路上, 于是给自己列了好些个备选考虑着要去哪儿玩合适,就近的天目山、千岛湖,远些的苏州、厦门,搜罗了游记来看。

天目山在临安,据说秋天的时候去会比较精彩,但景点说来说去好像就是几棵大树。千岛湖挺好的,老景区, 应该挺成熟的了吧;不过据老鸭的女朋友说,最近只开放两个岛,其余的都在养护。苏州自然也是不错的, 离杭州很近,大名鼎鼎的园林,蜚声中外的苏州博物馆,加上好多奇奇怪怪的加分原因(偶像钱钟书、张佳玮, 都是无锡人,同事里有常州、苏州、南通、徐州甚至连云港,让我对江苏整体上有个好印象,哈哈)。

不过真正准备出发的时间已经是春节假期里,我在瑞安,女朋友在温岭,天气又冷,于是决定往南走,去厦门。 决定了之后,买票、定旅店,都是女朋友搞定。定旅店的时候是年29晚上,她百度了个神奇的网站叫住哪儿网, 定了曾厝垵里一个神奇的青年旅社叫做逅海驿栈(起名字千万不要太多别字,打起来太累, 太容易用广为使用的那个代替)。然而等我们发现其实没有定成功的时候已经是正月初五的晚上11点钟了, 我们拖着行李在环岛路上走了好久。

因为买不到合适时间的车票,我们的时间安排很奇葩,初五晚上到厦门,住曾厝垵一晚,次日玩厦大、环岛南路等, 再住曾厝垵一晚,第三日早晨往鼓浪屿,玩一天,住一晚,第四天一早赶往火车站,回家。三晚,才玩两天, 都是让车票给害的。当然,如果能够早一些些,初三、四就出发,应该能好很多。

初五,我老妹开着送我们去瑞安飞云的火车站。彼时恰好雨过天晴,途径飞云某地时,锦山秀水,云萦雾绕, 很是好看。飞云的动车站,建成有些时候了,刚投入使用的时候,连停车场都没好,一出站全是站着的出租车、 黄油车司机,夹杂着来接乘客的人,乱哄哄的,配合坑洼的地面,很有三线小城市的感觉。不过此番我们去, 已经好多了。

检票、进站、候车,按下不表。从瑞安往南,风土没太大变化,隧道、海岸、湖泊、寺庙。气温倒是一点点往上升, 等到晚上9点多我们到厦门,发现好多人穿得薄外套,比起瑞安暖和得一塌糊涂的时候,内心还是有点小澎湃的。 我们到的是厦门北,直接打车略贵,但可能因为车站管事的下班了,车站没有一辆出租车是老老实实拉客的, 全都拿自己当黄油车使,不打表,乱拼车。于是坐了往厦工大思明校区的公交车,决定到思明区再打车。 一个很囧的事情是,我们零钱不够⋯⋯ 不过还好有个同车的从上海过来的帅哥给我了一块,救了江湖之急。

一般说去厦门玩,指的都是厦门岛与鼓浪屿,推荐的景点不少,但最出名的还是厦门岛南部的中山路、 环岛南路以及厦门大学,和鼓浪屿。在我们坐公交车进岛的时候,路过集美大学,彼时内心只有一个感慨, 真骚包啊⋯⋯ 集美大学的教学楼是欧式的,看着跟城堡似的,景观灯布置得也很好,各种美。马路边的绿化, 跟杭州比感觉是另一番世界,另一种风格了,但一样的干净。

接近终点站的时候,马路边看到家卖沙茶面的店,很诱人,就跳下车宵夜去。麻辣烫,点了一堆吃的, 主食自然选沙茶面。桌上有辣酱甜酱,不怎么辣,加了些。内心戏是樱木吃到晴子做的面,真好吃啊。 吃完我们打车到了曾厝垵,这小渔村直接给了一个下马威,往里走的路错综复杂,跟我小时候读书的湖岭镇老街差不多, 要找那个逅海驿栈可真难了。站在环岛路边,卖水果的大叔说,让店老板出来接你还差不多。于是打电话、 等老板出来,发现预约失败,但幸好还有空房,于是好歹住了店。

第二天醒来曾厝垵接着给了我们一个大惊喜,这里的路牌是没有顺序的,抽签的! 于是大众点评上推荐的神马吃的我们是完全只能碰运气找了。早饭去了家看着挺洋气的店,原谅我想不起店名了, 海鲜粥、排骨面,中规中矩。出来之后接着各种坑爹,在垵里胡乱晃悠,不过这小渔村却是挺好,很干净, 房子各种美。门脸儿都很风骚,院门有文艺的有复古的有装高门大阀的。也有不少老房子。

曾厝垵里的老房子

后来我们靠着指南针走了出来,到了环岛路,打车,第一个目的地厦门大学。出租车司机挺好,推荐我们说, 从厦大西门进,先看厦大白城,比较有趣。自然从善如流。

IMG_8947

IMG_8969

忘了说这一天的天气,晴,最高温度二十多度,跟我记忆中的正月初六天差地远。在这样的天气, 逛厦大白城,看里头各种南洋风格的植物(原谅我,真的叫不来),感觉奇妙。

IMG_8946

IMG_8972

逛了个把时辰,看到有后山,联想到老和山上鸟瞰玉泉校区,我便想上山看看厦大,发现拦住了上不去, 也没有好走的山路。正研究着,小区里走出个好心大伯,指引我们铁丝网角落一缺口,告诉我们说,沿着这小路, 可以上山,还可以逃票进植物园。大伯是好心,结果办了坏事。这小路一开始还算清楚,上了山之后几不可辨, 我们赫然发现周遭从洋气建筑变成深山老林,当真有些慌乱,后来几经周折,胡乱摸索,翻了铁丝网又翻回去, 总算是重返人间。

回到校园,已过晌午,点评上推荐的厦大里的食堂没吃的了,于是决定出厦大,去顶澳仔路找吃的。 出门在外,大众点评很好用,搜索附近500米吃的,各种靠谱。在去那儿的路上,还买了个摊煎饼,木有油条, 包的是粉丝,很好吃!到了顶澳仔路,发现小吃挺多,著名餐饮连锁兰州拉面与沙县小吃, 自然也不缺席。我们去了一家评价还不错的咖啡店,叫黑糖(似乎各地都有连锁)。 服务员是老外,有点意外。

IMG_9017

吃完回来,逛厦大旁边的南普陀寺。这俩景点挺有意思,挨着。寺里全是人,游客、香客,和尚成了稀客。 不过游客引导工作做得倒很好,右边上左边下,川流不息。然后我发现很囧的事实,要俯瞰厦大, 从南普陀寺上山,有个很好的观景台,学校、海景,尽收眼底。我们之前爬得山,算是白费了。 姑娘说,老娘可爬不动了,不看也罢。只好半途折返,施施然出来,去找环岛南路上那片漂亮沙滩, 面朝大海,春暖花开一下。

IMG_9019

IMG_9025

时间是下午四点多,太阳小了很多,光线柔和,踩沙滩各种舒坦。沙滩就在演武大桥的西端,在沙滩上往西走, 有一段木栈道,在我们去的时候,近黄昏,散起步来真是风情万种。

走过这段木栈道,天色变暗,气温转凉,我们租了辆自行车回住处添衣裳。童鞋们贴的游记不假,在这段路上骑行, 真的感觉挺好,尤其是寻常见不到海的同学。在这路上骑车,旁边就是大海,往南看除了一两个海岛一望无际, 想想都起鸡皮疙瘩,文艺得一塌糊涂。

发现又拍相册只更新到南普陀寺,就先写到这吧,其余明天继续。

再度搬家

| Comments

从练手到如今吃这碗饭,我做了好多个网站,最早的用 Emacs Muse 学习 pluskid 做了个全是静态页的网站,叫过很多域名, 待过很多地方,但网站的名字一直没变:《采薇采薇》。然而在我就职的首家公司, 技术以 J2EE 与 Flex 为主,用 Emacs 的机会并不多,于是后来又跟风用 stacey 制作了新版的个人网站,展示的是自己的画、 和一点点浅薄的技术积累。

到了 2012年,我的工具包又发生了变化,多了 Ruby,Git,与 Vim,套用句广告词, 世界每天都在变,于是我再度追新,用上了 jekyll。牵引后果,技术考量, 在我之前的博客中我已经说过,不赘述。

与过去相比,今年另一个大变化是,我与人合租了个 Linode VPS, 于是我把篇首提到的俩网站拾掇拾掇,都给放了出来,斗胆贻笑大方。它们分别是 2008.cyj.me2011.cyj.me。 VPS 与 Dreamhost 等空间相比的好处是,许多技术细节直接暴露给我, 使我在搭服务的时候学习到不少东西。如果不是因为 bus.fm 与 luoo.net 要放上来, 我可能根本用不到 nginx 的任何相对复杂点的配置,也理解不了三层逻辑: http - server - location。在此向诸位推荐这两篇入门介绍: Nginx PrimerNginx Primer 2 - From Apache to Nginx

我选的 Linux 发行版是 Arch Linux,以前有篇推介, 用到一个词:“滚动发布之美”。意思就是 Arch Linux 是没有固定版本号的,永远最新。 同时,Arch Wiki 文档翔实, 让我配置 FTP 与 VPN 等服务时方便许多。

你可能注意到,虽然这个 cyj.me 是个全新的版本,但内容已经很丰富了。 它们都来自 blog.cyj.me,我从 2008年开始一直都在更新的博客。 但在导入的过程中,我删掉了其中一些简单的转发、短评文章,并深深自责过去写文的随意。

接下去的日子,就是技术、照片与其他的更新,这里再不会出现速食新闻式的各种转发了。 而 blog.cyj.me 则不再更新。

莞尔

| Comments

博客从2008年开始写,中间转发了许多幽默、轶闻,如今看来,很可乐,但意义不大。 今天得闲重读,便将其中篇幅较短的收集起来,统一放到这里,不单独放出了。


quote from slashdot.

  • A stale piece of bread is better than nothing.
  • And nothing is better than a big juicy steak.
  • Therefore a stale piece of bread is better than a big juicy steak.

bin-laden.sh
1
2
$ chmod a+x /bin/laden
$ # Every one is entitled to execute bin laden.

达特茅斯大学计算机科学学院的 关于王道也不可信的列表


一个bs GPL 和偏执狂 RMS 的文章

BSD、MIT、CC 等授权似乎比所谓的 Copyleft 更受欢迎嘛。


Everything that is old is new again.

Two lions escape from the zoo. They decide to split up and meet back in two months to see how the other is doing.

Two months later, one lion is scrawny and beat up, the other is fat and happy. The scrawny beat up lion says, “I went to the park and started eating children. The police and national guard came after me and I haven’t stopped running since. How are you so well fed?”

The second lion replies, “Easy! I Just hid outside the IBM office and ate a manager every day. Nobody even noticed!”

两只狮子从动物园逃了出来。他们决定分开行动,两个月后再在此地见面看看彼此过得如何。

两个月后,其一骨瘦如柴、挨了不少揍,另一个却显得很富态。瘦狮子说:“我跑去公园吃小孩。 被警察和太保追着打。打那以后就一直疲于奔命。你在哪混的伙食?”

第二只狮子回答说:“简单!我躲在 IBM 办公室外头每天吃一个中层管理人员。根本没有人注意到!”

这是 Slashdot 上对微软、Intel、IBM 相继裁员的新闻的回复。

也让我想起了老友记里头 Chandler 童鞋的那些办公室笑话。比如当同事抱怨事务繁忙、上级分派任务繁杂的时候, 他说,为啥不把通知丢到碎纸机里头,如果头头来问就说你从来没收到通知?同事当他说笑,他很严肃地自言自语, 为啥我说正经的的时候,你们老当我在开玩笑……

ps:该新闻说,微软与 Intel 都将裁员5k余,而 IBM 则尚未通报确切数字,据传将达到 16k。


当 Steve Jobs 遇到 Donald Knuth

Steve 童鞋邀请到了高德纳来给 Mac 团队做个小指导。高德纳是斯坦福大学计算机科学系的传奇教授。 (还有一篇g9写在高德纳70岁时候的文章也可以看。)

我还坐在 Steve 的办公室里头的时候,Steve 的助手 Lynn Takahashi 童鞋报传高德纳驾临。 Steve 小盆友从板凳上跳起来,赶紧开了门并伸出了欢迎的手,就差倒着穿鞋子了:

“见到你真高兴。” Steve 说,“你的书我都读了。”

“你放屁。”高德纳回答。

Steve had managed to get Don Knuth, the legendary Stanford professor of computer science, to give a lunchtime lecture to the Mac team. […]

I was sitting in Steve’s office when Lynn Takahashi, Steve’s assistant, announced Knuth’s arrival. Steve bounced out of his chair, bounded over to the door and extended a welcoming hand.

“It’s a pleasure to meet you, Professor Knuth,” Steve said. “I’ve read all of your books.”

“You’re full of shit,” Knuth responded.

(此处略去高德纳介绍,详情请见g9对他的介绍


居家旅行杀人越货必备之注释工具

the commentator

通过一些很囧的参数设置,让注释工具了解的你的性格,就可以开始注释了。

wtf.c
1
2
3
// avoid using the reverse "i >= 0; i--" style loop here,
// it would obviously be more efficient, but blows up in gcc
// under linux and solaris

FUD 开太大的话就是这结果……


一家大公司的计算机(故事背景在计算机还很巨大的年代)挂掉了,所以他们给维修工打了电话。 修理工在真空管架子之间走来走去,背着手哼着小曲,左看看右看看,上看看下看看。 公司经理跟在后面紧张兮兮地探头探脑。

过了一会,他终于在其中一个架子前停了下来。那个架子并没有什么与众不同的地方。 他拉出真空管的托盘,拿出一个来放进自己的口袋。又从自己的另一个口袋里头掏出一个新的来, 插回去。他接着把托盘推了回去,同技工说,开起来吧。

计算机又妥妥儿的了。

经理很高兴:“太好了!谢天谢地它又跑起来了!我们要给你多少钱?” 修理工说:“一千刀。”(在计算机还是真空管的年代,这钱可真不少。) “什么?!一千块买个真空管?我要个详细的清单收据!” 修理工耸耸肩,从兜里掏出个小本,写了一会,递给经理。经理拿来一看:“真空管:一刀;找到要更换的真空管:999刀。”

via

难得在 proggit 上又看到这则笑话,或者说寓言,翻译一下,聊作记录。小学的时候好像看到过,不过那时候修的是别的生产设备。


via

Welcome to the new decade: Java is a restricted platform, Google is evil, Apple is a monopoly and Microsoft are the underdogs


粉絲們為 JavaScript 大神發起了 Twitter hashtag #crockfordfact, 有愛的“軼聞”都放在 Crockfordfacts.com摘錄一條

Douglas Corckford can have full conversations using only javascript’s reserved words.


Linus Torvalds Facts,很 KUSO,其中一条:

Linus Torvalds doesn’t wear glasses anymore not because he had laser eye surgery, but because he finally got his xorg.conf properly configured in his head.


用 QUnit 做 JavaScript 单元测试

| Comments

前一阵跟同事讲 JavaScript 单元测试该如何搞起,找了些资料, 结合自己的应用情况,说了一些,但依然说得不好。因此写篇博文,记录一下。

按专业做测试的童鞋们的划分,单元测试属于白盒测试。做法是, 与待测模块使用相同的程序语言,引入该模块,引入测试框架,然后噼里啪啦写一堆测试用例。 Ruby 童鞋这一点做得很好,自带了一个 test/unit,Rails 童鞋更进一步,在 项目根目录的 test/unittest/functional 下分别会生成对应 model 与 controller 的测试类。同时还补上了一坨断言,详情请看 Rails Guides 之测试

JavaScript 短小精悍,自带的东西除了各种神奇语法,啥也没有;有一堆所谓的 Juicy Libraries 可供挑选,结果经常因为想用 B 框架的甲插件,自己却已经用了 A 框架而心生惆怅。其实兼收并蓄也没什么不好,大家网速都还可以的嘛。

扯远了哈,我的意思是,要做 JavaScript 单元测试,第一个问题就是先得挑一个框架。 StackOverflow.com 上有人弄了个 详细列表 ,有些已经陈旧了,例如 JSUnit,有些则偏整体测试解决方案一点,例如 John Resig 做的 TestSwarm.com。

我们先讲语言层面的测试框架本身好了,现在用得比较多的是 JSSpec、 Jasmine 和列表中没有提到的同是 John Resig 的作品 QUnit

先被我排除的是 JSSpec,因为在我接触到的前端项目里头,要么没有写单元测试, 要么没有用 JSSpec,所以我一直没有见过 JSSpec 的单元测试语法是什么样的; 不过把它列入考虑的原因也简单,没有专门的测试人员的 Facebook, 写 JavaScript 单元测试用的框架就是它 (来源)。

SeaJSKissy 用的都是 Jasmine, 应该就是玉伯的偏好了。Jasmine 的语法效仿自 Ruby 里的 RSpec。 这种语法风格的宗旨是更贴近自然语言,直接从源码生成程序说明文档。

example.js
1
2
3
4
5
describe("Jasmine", function() {
  it("makes testing JavaScript awesome!", function() {
    expect(yourCode).toBeLotsBetter();
  });
});

但我不太喜欢,觉得有点不伦不类的。另一个让我最终没选它的原因是, 测试输出的部分还得自己包装,好麻烦⋯⋯ 参考玉伯 SeaJS 代码中 runner 部分。

所以我选了 QUnit。好啦,我终于切题了,下面讲 QUnit 的用法。

QUnit 包含两个文件,qunit.js 与 qunit.css,它的断言结果是输出到页面 DOM 里的, 所以基于 QUnit 写的测试,都需要有个 html 页面,引入这俩文件,并且保证页面中有这样的 DOM 节点:

test.html
1
2
3
4
5
<h1 id="qunit-header">亲爱的单元测试</h1>
<h2 id="qunit-banner"></h2>
<h2 id="qunit-userAgent"></h2>
<ol id="qunit-tests">
</ol>

你的测试代码应该长这样:

test.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
test("a basic test example", function() {
  ok( true, "this test is fine" );
  var value = "hello";
  equal( value, "hello", "We expect value to be hello" );
});

module("Module A");

test("first test within module", function() {
  ok( true, "all pass" );
});

test("second test within module", function() {
  ok( true, "all pass" );
});

module("Module B");

test("some other test", function() {
  expect(2);
  equal( true, false, "failing test" );
  equal( true, true, "passing test" );
});

在测试页面中引入这个,就齐活了。

QUnit 的 示例 有很多,jQuery 本身, jQueryUI 的部分项目,都用这货做的单元测试。

基本的测试用例搞完了,接下去要考虑的事是如何 自动化, 做持续集成。我尚无实际应用经验,先按下不表。John Resig 抱怨过 JavaScript 测试的烦恼处, 多平台、多浏览器测试使得一个小改动都需要大量人工去测,因此弄了 Test Swarm,对前端童鞋来说,文章很有趣,推荐一看。

此外,淘宝UED 的云谦童鞋,去年就搞过一个云测试项目,感兴趣的童鞋可以去了解一下。

搬家到 Octopress

| Comments

用 WordPress 写博客快四年了,一直有个痒处,怎么挠都不得劲,就是写文章的那框框实在是太不好用了。 后来又试过装 markdown 格式支持的插件,但不过是前端的一个包装而已,每次还得人肉去点 render,蛋疼得紧。

去年翻译 git-reference 的时候,第一次了解了 Github Pages 和使它所以为可能的技术基础 jekyll。 Github Pages 的中心思想是,可以建一个 yourname.github.com 仓库,在 master 分支里头放 HTML 文件, 通过 http://yourname.github.com 访问,也可以在你的项目仓库里头建分支 gh-pages,该分支里头放 HTML 文件, 通过 http://yourname.github.com/yorproject 访问。这两者都支持绑域名,在 CNAME 文件中填上域名, 在域名的 DNS 解析中加上 A 记录,指向 Github 的地址 207.97.227.245 就成。

精彩之处在于,Github 可以自动解析分支中的以标记格式为扩展名的文件,根据文件中声明的模板, 渲染出最终的结果。这就是 jekyll 做的事情:

  • 让你能够用趁手的编辑器写自己喜欢的标记格式(markdown、textile 神马的)
  • 让你拥有真正的版本记录
  • 无需网络就能撰写文章
  • 发布之后只有静态文件,轻便快捷
  • 无需数据库

前两点对我尤为重要,特别是在我立志要写牛逼文章的大背景下,咳咳。

无需数据之类的,我的 cyj.me 所用的东东,Stacey,就已经能够做到, 但它还是没脱 Web 服务的窠臼,只不过更新方式换成了 FTP 而已。但从这一点来说,更适合展现视觉方面的东东。

回到正题,我喜欢上了 jekyll,决定动手一试,于是翻看了篇 很优秀的介绍,看明白了大概, 但又觉得从头开始比较辛苦,恰好又发现它还提供 从各种平台迁移到 jekyll 的功能, 自然也包括了 WordPress:

$ ruby -rubygems -e 'require "jekyll/migrators/wordpressdotcom"; Jekyll::WordpressDotCom.process("wordpress.xml")'

呃,等等,我有点跳跃了,在做上面说的事情之前,要明确一个东西:

jekyll 不是记博客的软件,它是个解析引擎

所以,直接拿它替换 WordPress,你会遇到与我相仿的问题,有好多功能都没有,博客的设计还需要重头来过,等等。 但幸好,套用玉伯的话说,这个世界上聪明的人很多,很多事情别人已经做了。所以我找到了 OctoPress。此外也有人用 jekyll-bootstrap,丫还支持主题配置。但我并没有尝试后者。

现在接着说回上面的问题,直接执行上边的导入,导进来的文章内容是 html 格式的,自然不是我想要的。 所以参考了 yorkxin 的导入 gistJiang Le 的从 WordPress 切换到 Jekyll, 并使用了 downmark_it 将 HTML 转成 Markdown。

downmark_it 还算好用,但效果并非完美,还得略微调整一些小瑕疵。

我用的导入文章脚本被自己手贱删掉了,没能贴出来,灰常遗憾。

接着说一些细节上需要注意的,上述迁移任务并没有将评论导进来。由于是静态文件,jekyll 生成的网站也不支持评论。 但感谢 disqus,它提供了很风骚的纯 js 方式,令你的网页交互起来。更刺激人的事, 这货居然还能导入 WordPress 的评论,摆明了挖墙角啊。

此外,jekyll 中,categories: [‘computer’, ‘bug’] 的概念与原先 WordPress 中的概念是不一样的。 jekyll 里,会将 computer/bug 作为一个 category,所有标记为此类目的文章都归到此处, 不会在 computer 或者 bug 类目出现。而 WordPress 里的是彼此分开的。

最后说一句,如果不喜欢命令行,就不要使用啦。

Twitter Bootstrap 框架介绍

| Comments

第一次听说 Boostrap 是因为同事的 Ruby China,后来在自己负责的项目 一淘UX,后台部分的界面也用到了这个东东,用得有些束手束脚,因此决定把它的介绍看一遍,也给大家做个分享。

Bootstrap 是 Twitter 搞的一个框架,目的是有个工具可以方便快速搞起一个项目,样式部分使用 Less 写就,也提供了一些 jQuery 插件形式的扩展。对景德镇居民来说,它比较狠的是直接不支持 IE6,许多特效、属性在 IE7、8 里头也是捉襟见肘;因此,如果你的网站放不下这部分用户,还是先不要用了,或者可以参考着整一个自己的版本。Bootstrap 的代码托管在 Github,随时可以 fork。

样式方面,它提供了如下解决方案:

  • 栅格系统
  • 布局
  • 字体样式
  • 多媒体展现
  • 表格
  • 导航
  • 警告与提示
  • 弹出浮层

栅格系统与比较著名的 960 Grid 大同小异,不过丫默认是16栏,940像素宽,此外一个特性是,因为 Less 带来的动态语言特性(变量、函数等),可以通过配置几个参数,自定义自己的栅格。因为抛弃了老旧浏览器支持,可以直接用 :last-child 将最后一栏的 margin-right 去掉,这也是它与 960 Grid 的差别之一。

布局也是老生常谈,一个固定宽度的居中,一个可变宽度的浮动布局。

字体设置里的风格比较明显,标题、em、strong、b、i 以及 address,都配了一些样式。在 blockquote 的样式里头,利用 before 属性,加上了个 &dash;。然后是列表,通过 .unstyled 类,获得样式充值效果;这个方式其实我也比较喜欢,特别是网站是以内容为主的时候。代码块也比较朴素,推荐了 Google Code Prettify

接着这个就比较贴心的了,很常用的 eye candy,内敛标签。

多媒体列表其实也比较简单,明确了三种缩略图尺寸 330x230、210x150 和 90x90。至于你的网站如何做,可能还是悉听尊便吧。表格的样式也是简约风格。

Bootstrap 对表单做了比较充分的定制,风格上比较明确,label 左浮动,圆角输入框。正确、错误的状态,表单 legend 的字号,前缀字符,输入、复选框等。文件选择的东东比较朴素,基本是老样子,也没有采用一些风骚的解决方案(那些基本需要与 JavaScript 配合搞)。表单的按钮也十分细致。

网站的全局导航栏,风格一以贯之,使用样式实现背景色渐变,固定在头部;同样,因为不需要考虑老旧浏览器,放心地 position: fixed; 就够了。

此外,还实现了提示、警告:

区块风格的消息提示:

面包屑导航:

翻页:

以上是样式的部分,是 Bootstrap 框架的主打。在代码上,基本把样式重置与定制都做掉了,上述内容,出了比较明显的组件如面包屑、翻页等,基本都是直接用标签做选择器的。不过,框架就该简单直接,对吧?有许多风格是利用较新的样式属性搞出来的,最明显的莫过于背景色渐变与圆角(gradient、border-radius、box-shadow 等)。因此,对于图省事、不介意老浏览器看起来效果差些,IE6 不需要管的开发者,Bootstrap 是个好选择,省时省力,美观大方。

在样式之外,Bootstrap 还提供了几个常用的 JavaScript 实现的效果。模态框、提示浮层、表格的排序等等,jQuery 插件的形式。夜了,按下不表。

RMagick、MiniMagick、ImageMagick、GraphicsMagick 傻傻分不清楚

| Comments

四兄弟都是 Magick 字辈的,要分清楚其实也简单。ImageMagickGraphicsMagick 是名副其实的两兄弟,都是开源的图片处理工具,具有丰富的执行参数,艺术效果等等。后者是前者的分支,从 2002 年时的 5.5.2 版本分出来,专注软件与编程接口的稳定性。

而 RMagick 与 MiniMagick 也算是两兄弟,后者比前者优势在更稳定,不容易内存泄露(That’s what they say…)。哥俩都是 Ruby Gem,是对 ImageMagick 的命令行选项的封装。中午查文档的时候瞥了一眼 MiniMagick 的些许代码,也是用的 method_missing 来搞。例如:

foo.rb
1
2
3
4

img = MiniMagick::Image.read(blob)
img.resize '800x800'
# method_missing thrown, resize wrapped as an option of `convert` command.

所以,基本上对着 ImageMagick 的文档用就是了。

然后再提一个经常用到的实践,在 CarrierWave 的封装里头也很常见的,resize_to_fit 与 resize_to_limit,以及其他一些需求,例如我今天要做的,把图片宽度限制在 800 以内,高度不限。这种需求都可以通过 -resize 参数统统搞定。在文档里头我们看到,它说接收一个 geometry 格式的参数。那这个 geometry 参数长啥样嘞?

scale%  Height and width both scaled by specified percentage.
scale-x%xscale-y%   Height and width individually scaled by specified percentages. (Only one % symbol needed.)
width   Width given, height automagically selected to preserve aspect ratio.
xheight Height given, width automagically selected to preserve aspect ratio.
widthxheight    Maximum values of height and width given, aspect ratio preserved.
widthxheight^   Minimum values of width and height given, aspect ratio preserved.
widthxheight!   Width and height emphatically given, original aspect ratio ignored.
widthxheight>   Change as per widthxheight but only if an image dimension exceeds a specified dimension.
widthxheight<   Change dimensions only if both image dimensions exceed specified dimensions.
area@   Resize image to have specified area in pixels. Aspect ratio is preserved.

这货定义的真是太精彩了,言简意赅,上面的那些需求都可以分别满足:

-resize 80x80
-resize 80x80>
-resize 80
-reszie 80x800< # 如果刷屏金箍棒出现

不过话说回来,在可读性与简洁之间,确实很难做好平衡呢。

事件代理以及它的好处

| Comments

不是什么新东西了,昨天做的分享里头需要讲到,又把几个知识点翻出来看了一下,这篇博客总结得不错,摘译一些。

事件代理利用的是事件冒泡机制,在事件,例如点击触发时,是从 DOM 树最底端的阶段开始往顶端冒泡,事件对象贯穿这个生命周期。入门事件绑定的时候,绑定与处理是这样的:

old.js
1
2
3
4
5
6
7
8
var button = document.getElementById('J_button');

button.onclick = function(e) {
   e = e || window.event;
   var target = e.target || e.srcElement;

   // handles target
};

这在要绑定、处理的节点多了之后有点难办的,尤其是列表、表格这种场景,在 for 循环的时候,有个经典的 js gotcha:

wrong.js
1
2
3
4
5
6
// 错误代码
for (i = 0; i < anchors.length; i++) {
    anchors[i].onclick = function(e) {
        alert(i);
    };
}

不管点那个锚点,alert 出来的都是 anchors.length -1,熟悉 js 的都会告诉你,这是因为闭包的关系,因为等你点击任意锚点的时候,这个 for 循环执行已毕,当前上下文,也就是 onclick 所在的闭包,里头的 i 已经是 anchors.length -1。

而如果用事件代理的方式,则强迫你放弃闭包中的这些循环变量:

delegate.js
1
2
3
4
5
6
7
8
anchors_box.onclick = function(e) {
   e = e || window.event;
   var target = e.target || e.srcElement;

   if (target.tagName.toLowerCase() === 'a') {
       alert(a);
   }
};

如果需要 i,则需要在事件处理时去实时获取,或者预处理一下,将 i 放到它们的属性里头去。两者对比,采用事件代理方式的好处显得清楚明了:

  1. 绑定起来更加方便
  2. 减少闭包使用,从而降低可能不必要的内存占用
  3. 对代理节点的 innerHTML 做修改,不需要重新绑定
  4. 在事件监听节点比较多的情况下,特别是重型的 OPOA,跑得更顺畅

参考文章

忐忑 2012

| Comments

2012 年开始了,没有船票的我内心忐忑,不管末日与否,还有12个月要过的,给自己定几个目标:

  1. 吉他接着搞起
  2. 每天画点小画
  3. 各种 webapp 搞起
  4. 工作上还得再接再厉,NodeJS 有必要搞起
  5. 理论知识得熟络,联系实际能力要加强;看一遍《SICP
  6. 和林妹纸一起,去更多更远的地方
  7. 多关心家人一些

不敢写具体了,怕食言而肥。努力吧。

回顾 2011

| Comments

去年果然很忙,例行的新年计划都木有,翻了翻历史,只有对 2010 年的展望,笑言希望买单反,如今快门数估计已经过万不止了,以及对这篇展望的回顾。大体上上说,2010 年完成得不错。

2011 年,年初没有定目标;而公司的个人 KPI 设定又略显偏工作内容了,不好提。只好按月份回顾一下罢:

一月份前后,开始学 Ruby on Rails,之前用过的语言与框架是 Python 与 Django,转到了 Ruby 与 Rails,许多技术思想其实相差无几,但语法差别、接口细节之类,也有些恼人,磕磕绊绊,边干边学,还算顺利。一月份看了两部电影,《黑天鹅》与《How To Be》,艺术追求与自我价值的找寻,娜塔莉·波特曼与罗伯特·帕丁森各自过着拧巴的日子。

二月份,博客里记的仍然只有技术文,中间其实有个很生活的片段,就是农历新年。正月里去怕了温州最高的山,金鸡山(照片),上山太早,冻了俩小时才看到日出;下山的时候第一次与别人刮擦,是个悍妇,扛不牢。这一年春节,也是大学毕业之后,工作两年多,头一回能在家待超过十天。回杭之后,还提了车,开始每天烦恼停车位。二月份看了一部电影,《非诚勿扰2》,谈恋爱是美好的,婚姻还是得一步一步来,行差踏错,麻烦得很。

三月份,木有记。去了一趟安徽家朋,和新安江上游,看到了许多油菜花田,看到了一棵超大的樟树。那边有个地方叫做磡头,跟我念小学时的镇上十分相似,有种穿越回九十年代的错觉。本月看了三部电影,《Gone Baby Gone》,Affleck 兄弟出品,剧情跌宕,没有了绝对的好人坏人了;《前度》,前男友前女友什么的,都是洪水猛兽;另一部是口水片,不评价。

四月份,翻译完了 Git 参考手册,很短的,领到了模样十分美帝国主义的 MacBook Pro,各种努力适应。清明的时候还去了青山湖打酱油,随便兜了兜,仰慕了一番湖边的别墅们。还去了杭州花圃、太子湾。那个时节去这些地方显得比较入时,对吧?四月份的电影十分精彩,《里约大冒险》是个很不错的 3D 动画片;《我是 Sam》是个很可爱的老爹,以及一首很萌的歌,lucy in the sky with diamond. 《将爱情进行到底》也十分有趣,尤其是在五菱里头车震被交警拖走那段。

五月份,记的只有两件事情,喜欢的两个球队都完败,曼联挂了,湖人也挂了。不过我久不打大球,又不喜做个纯球迷,得勉励自己要么索性不看,要么得开始篮球、足球择一恶补了。其间在枫华府第的单身公寓小住了几日,走路去上班的感觉真好,晚上不睡觉,跑去拍夜景。五一的时候,还开车回了趟家,第一次跑告诉,回来的时候一个人,开得有点累,但感觉也不坏。和老鸭、九九去了西溪湿地,还去了老余杭那边的薰衣草园(其实不是薰衣草,学名叫啥忘记了)。车子首保。五月的电影精彩纷呈,《国王的演讲》、《玫瑰人生》、《不一样的天空》、《危情三日》、《速度与激情5》都很值得一看。

六月份是个惊悚的月份,因为女朋友要毕业了,很庆幸现在还在一起。六月份有一部电影很值得看,《打擂台》,很有令我心折的港味。

七月份啥也没记,女朋友返家过最后一个暑假。去参加了 iConference,了解些 iOS 开发相关的东西,但到底没能立马动手开始做起来;回家赴飞腾订婚的宴席,就在我坐 D3115 回家两天之后,这班车与 D315 发生追尾,举国震惊。这月还有个很囧的事情,喝醉酒把自己手机搞挂了。

八月份,小兹兹被刮擦,对方全责,这人是我见过态度最好的车主了。爸爸妈妈和妹妹来杭州小住,陪我过暑假,待了一个星期多些,感觉家里从里到外新了一圈,真正的蓬荜生辉;女朋友也返杭了,送了我一只摇头狗狗,作七夕礼物。更多8月照片,在这里。这一月,《哈利·波特》系列完结,变形金刚出到3,还补看了《斯巴达克斯·血与沙》。

9月份,《钢的琴》是一部触动人的电影,亚马逊发布了新版的 Kindle,而我则趁着中秋小长假,和女朋友去了趟南浔和乌镇玩,照片请看这里。又回了趟家,大林伟订婚;后来还跟老鸭去了趟滨江的垃圾街,烧烤狠不错,偶尔吃一顿,感觉很好。

十月份,又回了趟家,项目发布,烟花节,去了趟之江玩,夜晚的时候遇到一只很萌的猫,后悔没有带回家。部门组织架构调整,成了一淘-UX-广告组的成员,大老板是个有趣的人。这个月,我24岁了。

十一月,同学们各种婚礼,本科室友,高中同桌、公司同事,都有结婚、订婚,送红包不迭。拍了许多照片,看到新郎官落泪,致辞的时候哽咽,被触动了。月底的时候,女友的妈妈来杭,接到家小住两日,做司机载着两位女士在杭州各处跑,第一次发现秋天的杭州(照片)这么美。

十二月,刚过去,给女朋友庆生,第一次喝好贵的茶,吃好贵的蛋糕,去许多没去过的店(三润居、21客、马灯部落、如拉小镇、BetaCafe、知味观、野鱼馆和台州小吃)。弄坏了 Kindle 屏幕,又花400块换了块新的,然后效果似乎有差。另一个项目上线,但都还忙于各种调 bug。

流水账的 2011 年,生活上一片忙乱,工作上也好不到哪儿去。然而毕竟没到求稳的阶段,还得再努努力,多快好省,搞定工作,享受生活才是。

明天找时间想想 2012 年该如何吧。