读书人

[初学者自学五]富文本编辑器

发布时间: 2012-02-11 09:51:34 作者: rapoo

[菜鸟自学五]富文本编辑器
看到精华区有个富文本编辑器.自己参考着样式也写了一个.由于时间有限BUG不可避免.希望大家提出好的建议.如果有时间我会再重构一次.

代码下载和具体细节请参考
http://www.cnblogs.com/goodness2010/archive/2010/03/25/1695241.html

由于代码较长分两次发
程序源码上半部

JScript code
// JS编辑器 // @version beta 0.1// @date 2010-03-21// @author goodNess// @blog http://www.cnblogs.com/goodness2010/// @email goodNess2010@126.comvar co = co || {};co.Root = 'http://www.cnblogs.com/images/cnblogs_com/goodness2010/238089/';  // 图片的根目录// 浏览器判断co.browser = (function(ua) {    var b = {        msie: /msie/.test(ua) && !/opera/.test(ua),        opera: /opera/.test(ua),        safari: /webkit/.test(ua) && !/chrome/.test(ua),        firefox: /firefox/.test(ua),        chrome: /chrome/.test(ua)    };    var vMark = '';    for(var i in b) {        if(b[i]) { vMark = /(?:safari|opera)/.test(i) ? 'version' : i; break; }    }    b.version = vMark && RegExp('(?:'+ vMark +')[\\/: ]([\\d.]+)').test(ua) ? RegExp.$1 : 0;    b.ie = b.msie;    b.ie6 = b.msie && parseInt(b.version) == 6;    b.ie7 = b.msie && parseInt(b.version) == 7;    b.ie8 = b.msie && parseInt(b.version) == 8;    return b;})(window.navigator.userAgent.toLowerCase());// ie6图片强制缓存try {    co.browser.ie6 && document.execCommand('BackgroundImageCache', true, false);} catch(ex) {};// 获取ID对象co.getId = function(id) { return document.getElementById(id); };// 获取对象co.get = function(node) {    return typeof(node) == 'string' ? document.getElementById(node) : node;};// 创—OM对象co.append = function(parentNode, tag, attributes) {    var o = document.createElement(tag);    if(attributes && typeof(attributes) == 'string') {        o.className = attributes;    } else {        co.setProperties(o, attributes);    }    co.get(parentNode).appendChild(o);    return o;};// 遍历数组co.foreach = function(arr, callback) {    for(var i = 0, l = arr.length; i < l; i++) {        arr[i] = callback(arr[i]);    }    return arr;};// 设置属性co.DIRECT_ATTRIBUTE_MAP_ = {    'cellpadding': 'cellPadding',    'cellspacing': 'cellSpacing',    'colspan': 'colSpan',    'rowspan': 'rowSpan',    'valign': 'vAlign',    'height': 'height',    'usemap': 'useMap',    'frameborder': 'frameBorder',    'type': 'type'};co.setProperties = function(element, properties) {    var val;    for(var key in properties) {        val = properties[key];        if(key == 'style') {            element.style.cssText = val;        } else if(key == 'class') {            element.className = val;        } else if(key == 'for') {            element.htmlFor = val;        } else if(key in co.DIRECT_ATTRIBUTE_MAP_) {            element.setAttribute(co.DIRECT_ATTRIBUTE_MAP_[key], val);        } else {            element[key] = val;        }    }    return element;};// 属性扩展co.extend = function(destination, source) {    for(var property in source) {        destination[property] = source[property];    }    return destination;};// 获取元素绝对位置co.getPos = function(o) {    for(var _pos = {x: 0, y: 0}; o; o = o.offsetParent) {        _pos.x += o.offsetLeft;        _pos.y += o.offsetTop;    }    return _pos;};// 设置透明度co.setOpacity = function(e, opac) {    if(co.browser.ie) {        e.style.filter = "alpha(opacity=" + opac*100 + ")";    } else {        e.style.opacity = opac;    }}// 事件绑定co.addEvent = function(el, type, fn) {    el.addEventListener ? el.addEventListener(type, fn, false) :     el.attachEvent('on' + type, function() { fn.call(el); })};co.target = function(e) {    return e ? e.target : event.srcElement;}// 禁止冒泡co.cancelBubble = function(e) {    if(e && e.stopPropagation) {        e.stopPropagation();    } else {        event.cancelBubble = true;    }};/** * 抽象单类工厂 * @method create(cfg{必须有一个唯一的id标识}) */var newFactory = function() {    var coll = {};    return {        create: function(fn, cfg, content/* POP_Body*/) {            if(coll[cfg.id]) {                return coll[cfg.id];            } else {                var win = fn(cfg, content);                 coll[cfg.id] = win;                return win;            }        }    }}();/** *  ---------------------------------- PopUp窗口辅助类 ----------------------------- *    config: *    id: 容器id *    title: 容器标题 *  container: 容器class *    concss: 标题内容样式 *    heacss: 标题外部样式 *    bodcss: 容器内容样式 *    chicss: 内容子列表样式 *    content: 子列表内容 *  @describe clicking on an element with the unselectable attribute set to on does not destroy the current selection if one exists. */var popUp = {};popUp.create = function(config, body) {    this.container = co.append(document.body, 'div', config['container']);    this.container.id = config.id;    var _head = '<div class="' + config.heacss + '"><span class="' + config.concss + '">' + config.title +'</span></div>';    var _body = '<div class="' + config.bodcss + '">';    _body += (body || '');    _body += '</div>';    this.container.innerHTML = _head + _body;    return this.container;};/*--------------------------------- ColorPicker辅助组件(单独提出.松耦合) -------------------------------------------*/var ColorPicker = {    create: function() {        // 定义变量        var cl = ['00', '33', '66', '99', 'CC', 'FF'], a, b, c, d, e, f, i, j, k, T;        // 创建整个外围容器        this.win = co.append(document.body, 'div');        this.win.id = 'colorPicker';        // 创建head        var h = '<div class="colorhead"><span class="colortitle">颜色选择</span></div>';        // 创建body [6 x 6的色盘]        h += '<div class="colorbody"><table cellspacing="0" cellpadding="0"><tr>';        for(i = 0; i < 6; ++i) {            h += '<td><table class="colorpanel" cellspacing="0" cellpadding="0">';            for(j = 0, a = cl[i]; j < 6; ++j) {                h += '<tr>';                for(k = 0, c = cl[j]; k < 6; ++k) {                    b = cl[k];                    e = k == 5 && i != 2 && i != 5 ? ';border-right:none;' : '';                    f = j == 5 && i < 3 ? ';border-bottom:none': '';                    d = '#' + a + b + c;                    T = co.browser.ie ? ' ': ''                    h += '<td unselectable="on" style="background: ' + d + e + f + '" title="' + d + '">' + T + '</td>'; /* 切记设置unselectable='on'*/                }                h += '</tr>';            }            h += '</table></td>';            if(cl[i] == '66') h += '</tr><tr>';        }        h += '</tr></table></div>';        this.win.innerHTML = h;        return this.win;    }};/*--------------------------------- 编辑器基类 -----------------------------------------*/var editor = function(id, bardata, options) {    this.container = co.getId(id);    this.bardata = bardata;    this.currActive = null;    this.bookmark = null;    co.extend(this, this.setOptions(options));    // 创建框架结构    this.createStruct();    // 创建快照书签    co.browser.ie && this.saveBookMark();}; 



[解决办法]
不错呀,看看,先。
[解决办法]
帮顶一个
[解决办法]
不错不错,来jf了,LZ加油


话说,怎么只有事件绑定没有取消啊。。。。
[解决办法]
你真行
[解决办法]
不错不错
[解决办法]
目前正在研究中。。。。。。。。。。
[解决办法]
原来是你啊,哈哈,前天就在群里看见你这张图了,可惜我上班时间不能上Q啊
[解决办法]
我来顶你!
[解决办法]
强……
[解决办法]
谢谢楼主分享!
[解决办法]
嗯,继续支持LZ.
[解决办法]

[解决办法]
支持楼主。
[解决办法]
谢谢分享!
[解决办法]
很好,谢谢楼主分享
[解决办法]
哇,很强大
[解决办法]
很好很强大
[解决办法]
好东西 值得欣赏
[解决办法]
msie: /msie/.test(ua) && !/opera/.test(ua),

问下:为什么要加后面半句?
[解决办法]
好啊,好东西,支持
[解决办法]
牛人就是多
[解决办法]
好好,强大,支持,支持
[解决办法]
羡慕啊
[解决办法]
怎么高到分数啊

[解决办法]
.........mark..................
[解决办法]
支持~~~
[解决办法]
........
[解决办法]
学习。。。。
[解决办法]
探讨
引用:
msie: /msie/.test(ua) && !/opera/.test(ua),

问下:为什么要加后面半句?

因为opera尤其以前版本 只要通过工具栏的简单设置就可以模拟IE firefox的UA 所以为了防止伪装 就给他剔除.但最近版本比如我现在用的opera10就没那么容易了.

以前……

[解决办法]
挺不错的
[解决办法]
强大。。。学习。。。
------解决方案--------------------


火狐下看不了源码呀,难道是我的电脑问题?
[解决办法]
还可以哦
[解决办法]
[菜鸟自学五]富文本编辑器 [JavaScript]
[解决办法]
那里还用ua来判断 ?OPERA本身有WINDOW.OPERA你不用

假如按你的判断,如果是别人将ua设为ie的了,你这样判断,就不是列表中的浏览器了吧,
这样有可能导致一个根据浏览器的分支来执行的 语句根本没有执行的 机会了吧


探讨
至于你说的firefox 是因为那段代码firefox的判定是在opera之后得.所以在之前就一定确定为opera了就已经break了

[解决办法]
不错 楼主顶了http://www.ggsccn.com/
[解决办法]
a人生- CSDN社区 ...
[解决办法]
不错不错不错
[解决办法]
ASP.NET交流群(54017195)欢迎您的加入!
高手聚集,有你更精彩!

[解决办法]
好长啊
辛苦了
[解决办法]
学习.....
[解决办法]
谢谢分享!
[解决办法]
不错~~~~~~~~~~~!
[解决办法]
very nice
[解决办法]
very nice
[解决办法]
2222
[解决办法]
探讨

唉 我说你想要准备喷 也要把知识储备好再说吧. 我给你举个例子你看啊:
Opera伪装IE后的UA串为:
Mozilla/4.0 (compatible; MSIE6.0; Windo……

[解决办法]
jf.................................
[解决办法]
不错a!xuexi啦啊!
[解决办法]
en,bu怎么样
[解决办法]
顶一下,不知道能不能用
[解决办法]
可惜你用的是js啊,呵呵呵
[解决办法]
顶一下,不知道能不能用
[解决办法]
不错。学习了。
[解决办法]
谢谢 太好了
[解决办法]
太好了,谢谢
[解决办法]
标题看成了学富五车……up!
[解决办法]
这个不就是以前那个叫桃子的人写的???
[解决办法]
牛  支持顶 !!
[解决办法]
不错呀,支持!
[解决办法]
不错。支持下。
[解决办法]
学习下 哈哈

[解决办法]

每天回帖即可获得10分可用分!
[解决办法]
好东西呀!说不定哪天就能用上了!
[解决办法]
有些地方不懂,可以问问LZ么?
[解决办法]
真是 好贴啊。 我XXXX
[解决办法]
谢谢嘻嘻嘻
[解决办法]
佩服佩服。回头琢磨琢磨
[解决办法]
牛 收藏了
[解决办法]
每天回帖即可获得10分可用分!
[解决办法]
收藏。。学习。。
[解决办法]
学习了。
[解决办法]
这水平还是菜鸟??

楼主, 你逗人玩吧.

莫非你是天才.
[解决办法]
谢谢歇息诶ieiii
[解决办法]
相当强悍,学习学习在学习
[解决办法]
不错,顶个
[解决办法]
......................................................................
[解决办法]
厉害..
[解决办法]
不错,支持下
[解决办法]
楼主也算菜鸟的话 那就是菜鸟的楷模了
[解决办法]
感谢楼主分享,
慢慢
[解决办法]
不错不错不错 不错不错不错 不错不错不错 不错不错不错
[解决办法]
呵呵,谢谢分享。
[解决办法]
牛啊 值得借鉴!!!!
[解决办法]
ding yi xia ..
[解决办法]
感谢楼主
[解决办法]
牛逼,好强大

读书人网 >JavaScript

热点推荐