基础版在线演示已经放出
http://inedit.googlecode.com/svn/trunk/demo/demo.html
=====更新日志 =====
2008.12.18
改进了在FF只有一行数据情况下的BUG,当只有一行数据的时候自动添加空行以避免此BUG的发生.
===============
WYSIWYG WEB编辑器太多了。而且很多都很流行,功能也够强大。
可我还是要重新写一个,因为我发现:
- 改造问题 :如果要改造他们太难了,首先就是要很多的时间来理解作者的思路,然后要清晰的明白代码间的逻辑关系。好,我不怕麻烦,学习吧,可问题来了,这次改造完了,过了几个月,发现还有要改造的地方,还要重新的来一遍这个过程,怎么记不住?当然,作者的思路不是我的思路,或者说常常跟我的思考方式都是不同的,我真的是记不住。做笔记?成本太高了吧,又要做多详细的程度呢?
- 太长等待 :几乎所有的编辑器都是用的 iframe 方式另外包裹一个页面来完成的,到目前为止我仅仅发现 nicEdit 是 inline 式的,也就是利用 Element 的 contentEditable 属性为 true 来达到 WYSIWYG 的编辑目的。可是这个编辑器目前还不稳定,仍然有一些BUG没有处理,而作者自己的时间也不是很富裕,所以更新很慢。我等不了 nicEdit 了。其他的iframe的更不用说了,别指望作者按你的需求去设计。
- 策略方面 :为什么要用 inline 式的,而不用 iframe 方式?成本,制作好一个工具不管用多少时间费多少脑子,一旦完成,就可以快速的反复使用,所谓:工欲善其事,比先利其器 。inline 式比iframe方式的编辑器有一个减少成本的巨大优势:不用写两套页面了,一套浏览,一套编辑。一个好的 inline 式编辑器可以直接在浏览页面进行编辑,只要规划好向后台提交更新的代码,一个页面就可以兼顾两个功能,这无疑是提高了工作效率,减少了开发成本。因此一个好的 inline 式编辑器是很有实用价值的。
- 技术方面 :作为一个程序员,不要重复 造 轮子这句话真正的意思是不要造的是和别人造的一样的轮子才对(当然指的是技术选型并同样的功能)。因此我们需要尝试不同的方法去不停的造轮子。这样技术才能提高。程序员就是轮子工.对于这次的 inEdit 来说,inEdit 采用了与其他 javascript 常见技术完全不同的技术方法。我们知道 javascript 是面向对象的语言。但是大多数人认为的 OOP 就是要用 class 编程的方法,要用 new .这是很狭义的认识。OOP 绝对不是什么固定的代码格式所能定义的。对于 javascript 这样一个奇特的 OO 语言来说,更是可以充分的体现这一点:javascript 里根本就没有 class 这个概念,就算用 prototype ,原型编程 的方法也和其他语言 c++/java 的 new class 方式也是完全不同的两个概念。因此这一次我要用实作来还原 javascript OOP 的风格 。我把这种方法称为 Mixin ,混入 。Mixin 这个概念在别的语言里也有,我这里是借用了这个概念,不过 javascript 里的 Mixin 和他们不同,但是从方法上说也可以称之为 Mixin.在 Mixin 方式下,完全抛弃了 原型编程 的方法,甚至排斥不兼容它。
- 独立工具集合 :其实对于编程来说早就有这么一种理念:一段代码(函数,对象,库组件)应该只负责一件事情,这段代码应该独立简洁,并且有和其他代码融合使用的可能性 。传说中的小而美丽 .我们现在看到的很多库或者框架都是大而全,而且可组合性不高(当然有些组合是根本不必要的),相关性太高,鲁棒性太低。比如我们常见的javascript框架中都有each这种遍历对象并回调的函数实现,我问: 通常这种实现
1.传入对象可以是array 或 object,能是 function 么?
2.能灵活处理传入的对象类似 jQuery的实例对象(含有length成员且含有对应的以字符形式保存的数值作为 key 的成员)么?
3.能在回调函数里直接体现出是否是第一个成员,最后一个成员,奇数或偶数成员么?
不能
但是这些 功能真的很实用
不能传入 function 是因为就是 function 对象下定义了成员,但是不能通过 length 这属性来访问,因为function的length表示function的参数个数,就算不用length属性,直接遍历所有的成员,但是却又和上面的第2条有冲突,
第2条问题,其实是一个简化的访问操作,但是这个操作可能在某些代码里使用度很高,实现这个确很简单加入一个参数就行了
第3条就是更实用的功能了,比如我们要对表格的奇数行加一个不同的底色的话,方便的奇偶判断会使代码很简洁,同理要在弹出菜单中的每一行下加一条底边框,但是最后一个就不能加了,因为往往 弹出菜单的外围就定义了一个边框了,那判断最后一条就是很实用的了。所以要好轮子么?自己造吧!
还有就是从发展的角度考虑,很多早期的库,代码都有历史落后性,毕竟随着时间,需求和理念都在变,不同时期和环境是一定会有对应的代码理念的。这是发展的观点了。发展就靠我们自己来动手了 。
inEdit等基础版稳定后,稍后放出代码.届时会有相应的文章来说明我使用的具体方法。
先贴出我的each函数 :这个函数是某个基础对象的一部分
/*遍历对象,回调fun的参数:(v,k,['first','even','odd','lasteven','lastodd'])*/ each:function(obj,fun,bylength){ if(!fun && typeof obj=='function'){ var fn=obj,a=this; }else{ var fn=fun,a=obj; } var ret=0,odd=false; if(a instanceof Array) for (var i=0;i<a.length;i++){ odd=!odd; var even=odd?'even':'odd'; var at=i==0?'first':i==a.length-1?'last'+even:even; if(false===fn(a[i],i,at)) break; } else if (typeof a == 'object') if(bylength) for (var i=0;i<a.length;i++){ odd=!odd; var even=odd?'even':'odd'; var at=i==0?'first':i==a.length-1?'last'+even:even; if(false===fn(a[i],i,at)) break; } else{ var index=-1,j=0; for (var i in a) index++; for (var i in a){ odd=!odd; var even=odd?'even':'odd'; var at=i==0?'first':j==index?'last'+even:even; j++; if(false===fn(a[i],i,at)) break; } } else if (typeof a == 'function' && a.len) for (var i=0;i<a.len;i++){ odd=!odd; var even=odd?'even':'odd'; var at=i==0?'first':i==a.len-1?'last'+even:even; if(false===fn(a['0'+i],i,at)) break; } return this; }