第一个正式的开源项目 - 批量图片下载Firefox扩展

批量图片下载Firefox扩展是我08年做的一个小东西,当时是作为我发表在developerWorks中国上面的文章的示例应用而开发的。后来我把它发布到了Mozilla上面,现在有一万多的下载量,活跃用户900多。之前对Firefox 3.0的支持一直有问题,今天把它修复了。同时增加了对Firefox 3.5的支持。这个扩展目前看起来初见雏形了。于是我就把它源代码开放出来,成为我的第一个正式的开源项目。项目的地址在http://code.google.com/p/batch-images-downloader/

 

做这件事情的原因是今天收到一封来自西班牙的邮件,说他希望我的那个扩展可以支持最新的Firefox。既然有用户在用,我当然是很高兴的,于是就花了一些时间更新那个扩展。放到Google Code的好处是源代码能有比较好的管理,也可以让其他用户报告一些问题。

 

2009年互联网五大趋势(ReadWriteWeb) Top 5 Web Trends of 2009

ReadWriteWeb给出的2009年互联网五大趋势:

  • 结构化数据(Structured Data)
  • 实时互联网(The Real-Time Web)
  • 个性化(Personalization)
  • 移动互联网与延伸的现实(Mobile Web & Augmented Reality)
  • 物品的互联网(Internet of Things)

 

 

在Notepad++中使用Tidy来格式化HTML文档

Notepad++是一块不错的文本编辑器。在用Notepad++编写HTML文档的时候,经常会需要对文档进行格式化(pretty-print),主要是提供良好的缩进。通过Tidy插件就可以比较好的完成这个功能。为了Tidy正常的工作,需要在NPPTextFX目录下面(一般在C:\Program Files\Notepad++\plugins\NPPTextFX)新建一个配置文件:HTMLTIDY.CFG,该文件包含Tidy的配置选项,如:
 
indent: auto 
indent-spaces: 2
 
这样的设置就可以开启自动缩进的功能。更多的配置可以参考这里

IE 6/7 动态创建的单选框无法被选择

在IE 6/7上面,动态创建的单选框是无法被用户来选择的。这是一个已知的bug,并且在IE 8中被修正了。 已经有不少的资料在讨论这个问题了。对于这个问题,需要注意的是,如果要设置单选框的被选择状态(通过checked = true),需要在单选框已经被加入到DOM结构中之后来进行。

我也写了一个简单的页面来测试并修正这个问题。基本的思路是通过onclick事件来动态选择。基本的代码如下:

HTML页面中DOM更新时机的奇怪问题

最近在开发中遇到一个奇怪的问题,这个问题的场景是比较简单的,在一个DOM节点中首先要显示的是一条“正在加载”的消息,然后从远程获取一些数据,并显示在此DOM中。在Firefox下面,“正在加载”的消息能够正常显示,之后从远程获取的数据也能正常显示出来;但是在IE和Safari上面,“正在加载”的消息不能显示出来,DOM节点的内容先是空白的,只有等远程的数据拿到之后,才有内容显示出来。
 
后来进过分析,认为可能的原因是获取远程数据时包含了同步调用,导致DOM节点的内容通过innerHTML设置“正在加载”这条消息的时候并没有更新显示。不过只有Firefox上面正常,也觉得挺奇怪的。
 
解决的办法是通过window.setTimeout(func, 0)来把获取数据的方法人为的押后,这样让浏览器可以有机会去即时更新DOM,并显示“正在加载”的消息。这样一修改之后,在Firefox,IE和Safari上面都没有问题了。

推荐一款待办事宜的管理软件 - Task Coach

最近在用一款待办事宜管理软件,Task Coach,和其它的类似软件相比,我觉得有几点是不错的:

  • 对于任务的信息很详细。创建任务的时候可以填写的信息很多。一般的简单的todo管理软件,都只允许提供一个标题或是描述。这种对于那些简单任务是适合的,不过对于一些复杂任务,就不太够了。
  • 跟踪每件事花费的精力。很多时候我们都需要知道做一件事情花了多少时间,Task Coach提供工具可以自动计时。
  • 做事情的收益。可以管理做一件事情的收益是多少,然后与花费的精力做比较。

 
 

Windows 7体验之旅

因为我原来的XP系统很长时间没有重装了,速度有点慢,加上目前对Windows 7的评价都还不错,昨天晚上BT下载下来了一个Windows 7的镜像。今天下班回家就开始安装,整个过程挺顺利的。我是在XP的基础上直接全新安装的。把Windows 7的安装文件从镜像中拷贝到硬盘上,比如D盘下的win7目录,然后重启XP,按F8进入“带命令行的安全模式”,启动之后可以看到命令行,运行D盘下的win7/sources/setup.exe就可以进行安装了。安装完成之后,原来的XP系统会被放在C盘的windows.old目录下,不需要的话可以直接删除。
 
安装完之后发现启动过程还是比较华丽的,进入系统之后感觉也不错。驱动方面没什么大问题,只有老的AC 97的板载声卡驱动无法自动识别,百度一下找到一个,安装完就OK了。程序兼容性方面做得不错,下了360安全卫士、PPS、搜狗拼音输入法、Chrome都运行良好。

感兴趣的人可以试试,目前看起来还是不错的。

工作两周年记

2009年7月16号,是我工作两周年的日子。之前一周年的时候,我写了一篇文章作为纪念,所以今天也会要写一篇文章来作为两周年的纪念。

过去的一年,对于自己来说,比较大的变化是转到了产品部门,专门从事产品开发工作。也开始逐步接触国外的同事,开始加入全球化的大作坊中开始团队协作开发。这种状态到现在已经有半年时间了,其中的感触还是很多的。感觉自己也正在慢慢的适应和成长起来。工作的事情我觉得就不多说了,还是按部就班的慢慢来,还是分享一些工作之外的感受吧。

  • 让更多的人知道你 - 这其实是一件不太容易的事情,尤其在软件开发领域中,新的技术层出不穷,你很难总是保持在潮流的顶端。那我觉得每个人都可以试着去扩大自己的影响力,在技术的这个圈子里面寻找自己的位置。方法当然有很多了,写文章、写博客、做开源软件、做应用等等。我自己也做了一些这个方面的尝试,能够让更多的人知道你,是一件很有意思的事情。
  • 做正确的事情 -  每个人的精力都是有限的,选择正确的事情来做就显得尤其重要。当然选择的出发点可以有很多,我自己比较认同的一个说法是,从职业发展的角度出发,正确的事情就是那些可以写在简历上的事情
  • 把握时间 - 读完李笑来老师的《把时间当作朋友》一书之后,对于把握自己的时间更加有深刻的体会。所有人都想占用你的时间,如何把时间用在正确的事情上面,是件极其不容易的事情。我自己也在不断的摸索。
  • 先专后博 - 在对技术的把握方面,应该先对某个领域有一定深度的了解之后,再考虑拓宽知识面。

 

PS:这篇博文从7月16号一直写到现在,真是失败啊。

面向文档的数据库CouchDB初探

 面向文档的数据库目前比较流行,它可以作为通常的关系数据库的补充,在很多情况下,用文档的方式建模优于关系数据库的ER模型。目前流行的面向文档的数据库实现有Apache CouchDBMongoDB等。我之前花了一些时间研究CouchDB,主要是在如何用CouchDB作为一个应用服务器来开发Web应用。后来就写了一篇文章来说明其中的过程。对于CouchDB关注的朋友可以参考一下。(一万三千字呀)。

基本的摘要在下面:

 

CouchDB 是一个文档型数据库服务器。与现在流行的关系数据库服务器不同,CouchDB 是围绕一系列语义上自包含的文档而组织的。 CouchDB 中的文档是没有模式的(schema free),也就是说并不要求文档具有某种特定的结构。 CouchDB 的这种特性使得相对于传统的关系数据库而言,有自己的适用范围。一般来说,围绕文档来构建的应用都比较适合使用 CouchDB 作为其后台存储。 CouchDB 强调其中所存储的文档,在语义上是自包含的。这种面向文档的设计思路,更贴近很多应用的问题域的真实情况。对于这类应用,使用 CouchDB 的文档来进行建模,会更加自然和简单。与此同时,CouchDB 也提供基于 MapReduce 编程模型的视图来对文档进行查询,可以提供类似于关系数据库中 SQL 语句的能力。 CouchDB 对于很多应用来说,提供了关系数据库之外的更好的选择。

 

写完这篇的一个最大的好处是可以把电脑上面的Ubuntu给删掉了,6G的空间就腾出来了。

学习一下Retweet Button的代码

Retweet Button是John Resig写的一个简单的JS,用来把某个URL通过bit.ly的服务变短之后,发送到Twitter上去。 这个东西本来是比较简单的,代码也比较少,不过从中还是可以学到一些比较好的做法。

  • (function(){})(),创建一个匿名方法并马上执行,用来解决命名冲突的典型做法了。window.RetweetJS暴露一个惟一的全局变量作为入口点。
  • 通过<script>标签动态加载JavaScript文件。
  • var head = document.getElementsByTagName("head")[0] ||
    		document.documentElement;
    var script = document.createElement("script");
    	script.src = "http://bit.ly/javascript-api.js?version=latest&login=" +
    		RetweetJS.bitly_user + "&apiKey=" + RetweetJS.bitly_key;
    	script.charSet = "utf-8";
    	head.appendChild( script );
    

这种做法也非常常见了,与我之前的做法不同的是,如果没有head元素的话,就使用文档的根元素。

  • 对于onload的处理,自己习惯了dojo.addOnLoad,已经不记得背后的细节了。
  • if ( document.addEventListener ) {
    	document.addEventListener("DOMContentLoaded", loaded, false);
    
    } else if ( window.attachEvent ) {
    	window.attachEvent("onload", loaded);
    }
    
同步内容