Douban是2.0 社区里面比较成功的一个产品, 里面ajax技术也做得不错, 把它的源码拿来研究了一下, 它在页面上使用了jquery, 我比较喜欢它的一体式的事件处理机制,不用写很多的事件绑定代码,只需要通过一定的命名规则就可以自动给页面元素加上一些功能, 它上面几乎所有的功能都通过这个实现, 配合jquery强大的选择器,代码看起来比较简洁清晰. 下面我们就来看看它的一些核心部分. 我使用的是jquery 1.2.3,压缩之后29kb大小, 速度感觉上比以前有比较大的改善.废话不多说了,直接看看代码吧. 另外推荐一下blueprint 这个css框架,还挺好用的.
先看看效果图:


实现JS代码:
- //定义命名空间
- var Bowtech=new Object();
- //注册全局的事件监视器.
- Bowtech.EventMonitor = function(){
- this.listeners = new Object();
- }
- //广播事件
- Bowtech.EventMonitor.prototype.broadcast=function(widgetObj, msg, data){
- var lst = this.listeners[msg];
- if(lst != null){
- for(var o in lst){
- lst[o](widgetObj, data);
- }
- }
- }
- //绑定所有的事件.
- Bowtech.EventMonitor.prototype.subscribe=function(msg, callback){
- var lst = this.listeners[msg];
- if (lst) {
- lst.push(callback);
- } else {
- this.listeners[msg] = [callback];
- }
- }
- //取消事件绑定.
- Bowtech.EventMonitor.prototype.unsubscribe=function(msg, callback){
- var lst = this.listener[msg];
- if (lst != null){
- lst = lst.filter(function(ele, index, arr){return ele!=callback;});
- }
- }
- // Page scope event-monitor obj.
- var event_monitor = new Bowtech.EventMonitor();
- //对于所有 class="j a_xxx yyy" id="xxx-123"的元素执行事件绑定, xxx-123部分用来获取元素的ID,比如一个帖子的ID,
- // a_xxx 后面的部
- //分用来标识应用如 vote / review / blog 等.
- //绑定的事件就是 : Bowtech.init_vote / Bowtech.init_blog 等.
- function load_event_monitor(root) {
- var re = /a_(\w+)/; //正则表达式获取ID.
- var fns = {};
- $(".j", root).each(function(i) {
- var m = re.exec(this.className);
- if (m) {
- var f = fns[m[1]];
- if (!f) { //如果事件处理函数不存在则创建函数对象.
- f = eval("Bowtech.init_"+m[1]);
- fns[m[1]] = f;//调用绑定函数.
- }
- f && f(this);
- }
- });
- }
- //在文档加载完毕后将执行的方法(参见jquery文档)
- //一般来说文档加载的时候应该绑定所有的事件, 但是有一种情况例外.
- //比如 通过Ajax方法取回来的内容里面还含有动作按钮的,这时需要针对这部分功能执行绑定.
- //需要手动调用 load_event_monitor(element); 方法.
- $(function() {
- load_event_monitor(document);
- });
- //注意这里的o对象是一个html 元素而非是一个jquery对象,所以在调用它的方法时应该使用$(o)函数
- //把它转化为jquery对象.
- Bowtech.init_forder = function(o) {
- var eid = $(o).attr("id").split("-")[1];
- var fo = $("#f-"+eid);
- var unfo = $("#unf-"+eid);
- fo.click(function() {
- $(o).hide();
- unfo.show();
- fo.hide();
- });
- unfo.click(function() {
- $(o).show();
- fo.show();
- unfo.hide();
- });
- }
- jQuery.fn.extend({
- set_caret: function(){
- if(!$.browser.msie) return;
- var initSetCaret = function(){this.caretPos = document.selection.createRange().duplicate()};
- this.click(initSetCaret).select(initSetCaret).keyup(initSetCaret);
- },
- insert_caret:function(textFeildValue){
- var textObj = this[0];
- if(document.all && textObj.createTextRange && textObj.caretPos){
- var caretPos=textObj.caretPos;
- caretPos.text = caretPos.text.charAt(caretPos.text.length-1) == '' ? textFeildValue+'' : textFeildValue;
- } else if(textObj.setSelectionRange){
- var rangeStart=textObj.selectionStart;
- var rangeEnd=textObj.selectionEnd;
- var tempStr1=textObj.value.substring(0,rangeStart);
- var tempStr2=textObj.value.substring(rangeEnd);
- textObj.value=tempStr1+textFeildValue+tempStr2;
- textObj.focus();
- var len=textFeildValue.length;
- textObj.setSelectionRange(rangeStart+len,rangeStart+len);
- textObj.blur();
- } else {
- textObj.value+=textFeildValue;
- }
- }
- })
前台要用就比较简单了, 只需要这样写:
- <div id="test2" class="mod">
- <h3>
- 这里可以放标题
- h3>
- <div class="j modb a_forder" id="modb-1002">
- 这里是一些主要的内容
- <dl>
- <dt>Hello worlddt>
- <dd>
- hahahadd>
- dl>
- 这个实验在沙加的神舟本上完成
- div>
- <div class="edit">
- <a id="f-1002" class="forder" href="javascript:void(0);">[收起]a> <a id="unf-1002"
- class="unforder" href="javascript:void(0);">[展开]a>
- div>
- div>