keyCode 和 charCode

为了提取垃圾邮件中的中文字串,并自动转化为正则表达式需要的形式,我写了一个 Web 应用程序。只要鼠标选中字串,然后按下某个键,即可通过 Ajax 提交到后端转化和测试。自然我用的是 Catalyst 和 prototype.js。

原本我设定的是 Insert 键关联提交操作。而现在,我需要在提交的同时指定被选字串的类型,比如说邮件地址用 e 键,或者手机号码用 m 键,等等。这在当时开发的时候就发现, FireFox 下, prototype.js 只能返回功能键的 KeyCode,如果是字母,则一律是 0。我自然是不愿意因此屈就去用 IE 的,更何况我现在 Ubuntu 下面也没有 IE。而我有不想用 Mochikit,虽然实验过它没问题。我怀疑是 prototype.js 的问题,不过本着 Agile 开发的精神,没有深究下去。

这次,我决定解决这个问题。当然还是看了番源代码,做了些测试,未果。于是 Google,仔细找了下,发现枫岩的这篇文章,点醒我梦中人。简单的说,在 FireFox 中,KeyCode 返回 0 就用 charCode。于是我猜想 Mochikit 也是这样实现的:在 Signal.js 里第 135 行起定义的 key 函数非但给出了健壮的封装,还有一堆注解。

Ajax 忙碌图片集锦

什么是 Ajax Indicator ? 典型的,比如这个: 

在 irc 看到的,分享一下,有很多:

http://www.napyfab.com/ajax-indicators/

Google Ads

Comet

这是一个新名词,类同于 Ajax ,Comet 用于指代一种技术:服务器段保持长连接,任何时候都可以向客户端发送数据,反过来客户端也可以任何时候发送数据给服务端。典型的应用比如基于 web 的聊天工具,或者实时的股票行情现实。已经有一些商业的产品,比如 lightstreamer ,它的几个演示都非常专业。dojo 的作者 Alex 在他的 blog 上提到了这些想法,并打算用简单的术语称呼这种技术实现,并给出了和 Ajax 原理类同的原理说明图:

让人兴奋的是,他还提到 dojo 早就已经考虑到了 Comet 的实现,其中的 dojo.io.bind() 就是由此而生,并声称在未来的几周内提供演示。

Jemplate – Javascript Templating with Template Toolkit

今天一早来,很高兴看到能有这样一个模块。名字不太好读,不过很容易记。

http://search.cpan.org/~ingy/Jemplate-0.16/lib/Jemplate.pm

这个模块提供了一个工具,叫做 jemplate ,用来将 TT 的模板文件(可以是若干个)整合为某个 js 文件。结合该模块提供的另一 js 模板引擎 Jemplate.js ,在所使用的页面中,同时加载这两个 js 文件,于是你就有了在客户端,动态加载模板化驱动数据展示的能力。而这个数据则可以通过 Ajax 返回的 json 格式的代码获取。Damn cooool!!

第一个反应就是,我也可以做到和 Gmail 一样的多语言加载了。

JSON

http://www.crockford.com/JSON/说到数据交换,大体上我们的第一反应就是 XML 。严谨规范。Java 的世界里面如果不用 XML 来配置或者部署,就免不了有血统不纯的嫌疑。不过我不喜欢 XML ,好啰嗦。

然后在我们的应用中喜欢用 YAML 。一种人类可以直接读懂和修改的数据交换格式。它可以很简单,比 windows 下面的 ini 配置文件还简单,也可以很复杂,你可以把你的 Perl 代码中的对象序列化到 YAML 文件里,然后在 Java 里面构造出同样数据结构的 Java 对象来。让人爽得不行。

现在出来了个 JSON ,叫做 JavaScript Object Notation 。这里有篇介绍 。而 CPAN 上也有一个 Perl 模块 JSON,用来把 Perl 的数据结构转化为 JSON 。

JSON 有什么用呢?既然它是一个数据交换格式,我们就可以通过它来做比如远程调用。XMLRPC?现在可以 json-rpc 了。

现在广泛运用和讨论的 Ajax 技术,在后端从服务器取回来的响应一般有以下几种应用:

  • 返回的内容(html 代码片断)直接更新为 DOM 中某个元素的 innerHTML
  • 返回一段 Javascript 然后在客户端浏览器上 eval 运行
  • 返回一段 XML 文档,通过客户端对该 XML 文档的解析来同步更新多个 DOM 元素或者作出各种响应。

现在好了,我们可以返回 JSON 代码,然后通过客户端的 javascript 直接将它转化为 Javascript 的对象和数据,然后做各种你想要做的事情。我不得不说很酷。

目前公司的代理平台项目,我本打算做一个类似 api.xxx.com 的站点,提供 http post 请求,返回 xml 响应,以便客户端的 js (像 Rico 这样的 Ajax 引擎)来分析并处理。还好尚未有时间实施,看来用 JSON 更妥。

由 Behaviour.js 到 Degrader.js

Behaviour.js

Ajax 用起来很酷,可是你要要在 XHTML 里面写上 onclick,onmouseout,onkeyup 等等来触发调用一些 js function 。于是,Ben Nolan 在 http://bennolan.com/behaviour/ 上发布了 Behaviour.js 。和之前谈到的 FSA::Rule 模块类似,只要在 XHMTL 中给出 id 并且定义好一些 Javascript 的 Rules,并把这些规则注册到 Behaviour 引擎中即可。至于规则的定义,分三部分,也就是对谁在什么时候做什么事情。通过 css selector 来实现“对谁”,所以之前定义的 id 在这里派上用场了,也是 js 和 xhtml 只见的纽带。“在什么时候”,也就是相关的事件出发,比如一系列的 on… 事件。一旦发生事件,就触发去做一件事情,“做什么事情”也就是要做事情的 js function ,至于其中如何,随你的便了。

Degrader.js

Encytemedia 觉得 Behaviour.js 不爽,很多业务细节暴露在外面,也就是不够抽象。于是在这里(这是Part2) 发布了他自己改良的 Degrader.js 。废话少说,先看张图示:

通过对 id 名称的模式匹配,可以对许多个 id 绑定义系列的事件触发。所以,你只需要给出 pattern 并在 onMatch 的时候,动态注册一系列的事件观察(Event.observe),一旦发生了某个 event 就调用某个 function 。使用 Observe 设计模式,代码更为简洁优雅清晰。接下来该作者还会发布 Part3 给出一个实际的 RubyOnRails 应用。

此外,W3C 开始介入 Ajax 相关的领域,成立了 Web APIs Working Group ,开始要制定一系列的标准。看来真的要革命了。

Flex

很久以前就听说了 Flex ,Flash 为基础的 web 应用程序框架。有了 Flash ,什么复杂的界面都可以做了:

这是一个简单的 Feed 聚合的例子,你要做的就是定义好 XML 。这个简单的例子来自这里

与此类似的还有 XUL ,不过并非所有的浏览器都支持,界面自然也没有 Flash 那么令人愉悦。

将来的 web 编程方向?Flex or XUL ? even Ajax ? 天知道。哪天浏览器全面升级一下,现在的 web 应用模式和形式可能就要天翻地覆的变化了。有谁可以让全世界所有人同时全面升级浏览器?如果可以,跟本就不用像现在这么麻烦和无聊了。

Encodable Industries AJAX File Uploader

文件上传进度条。当然要用 ajax 来实现。这个 Encodable Industries 公司发布了免费的文件上传脚本,一个独立的 Perl 脚本 cgi ,专门负责上传并显示进度,如图:

除了进度条之外,还可以设置相关功能使用密码认证限制。其他一些特性比较普通。安装也比较简单。看了一下源代码,量不少,所有东西都在里面了。感觉如果变成一个模块就好了。有时间试试看抽象一下。总的来说还是不错的。

Catalyst 的作者以前说将来也会支持 Rails 里面的 Progress bar 只是不知道目前到底怎么样,呵呵。

Ajax 教程

http://dhtmlnirvana.com/ajax/ajax_tutorial/

当然我还没有仔细看,一共 37 页,大致浏览了一下,值得一读。本身就用了 Ajax 技术。

addEvent()

做 web 应用的人,经常会用到 Javascript 来处理页面上的一些事情。表单验证我们不谈,在根据用户使用情况,显示/隐藏,或者执行一段 js function,的时候,我们需要和页面的 DOM 树打交道。看看 Gmail ,发送邮件,按下“发送”钮后,用 Ajax 在后端发送邮件内容,根据返回的状态,在编辑页面的上方直接显示一小段文字“您的邮件已经发送。”。

通常的思想,我们会在那个发送按钮里面写上:

onclick="javascript:sendmail();"

然后由它来处理。Ajax 返回后,再触发另一个 show_status() 在 id=status 的对象中给出相关的状态信息。 复杂的应用的话,源代码里面满目的 html 和 js 混杂。不易维护,也不足够灵活。按理,XHTML 只是用来表示一个表示层的 DOM 树,JS 则对这棵树来做一些操作。交错混杂都谁都不好。

现在有了 addEvent() 和 removeEvent() 。问题就简单了。对一个 dom 对象,给出事件类型,给出所要触发的 function ,这个世界就清静了。你可以随时 remove 掉,换个新的事件处理。如此可以简化很多代码。quirksmode 搞了个比赛,ejohn 拿了第一名,他的实现是所有参与者中最简单明了的一个,在他的 blog 上给出了相关的说明和演示

addEvent( object, eventType, function );
addEvent( document.getElementById('foo'), 'click', doSomething );
addEvent( obj, 'mouseover', function(){ alert('hello!'); } );

使用之前,先把下面的代码复制过来:

function addEvent( obj, type, fn ) {
  if ( obj.attachEvent ) {
    obj['e'+type+fn] = fn;
    obj[type+fn] = function(){obj['e'+type+fn]( window.event );}
    obj.attachEvent( 'on'+type, obj[type+fn] );
  } else
    obj.addEventListener( type, fn, false );
}
function removeEvent( obj, type, fn ) {
  if ( obj.detachEvent ) {
    obj.detachEvent( 'on'+type, obj[type+fn] );
    obj[type+fn] = null;
  } else
    obj.removeEventListener( type, fn, false );
}