看到精华区有个富文本编辑器.自己参考着样式也写了一个.由于时间有限BUG不可避免.希望大家提出好的建议.如果有时间我会再重构一次.代码下载和具体细节请参考
http://www.cnblogs.com/goodness2010/archive/2010/03/25/1695241.html由于代码较长分两次发
程序源码上半部// JS编辑器 
// @version beta 0.1
// @date 2010-03-21
// @author goodNess
// @blog http://www.cnblogs.com/goodness2010/
// @email [email protected]
var 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;
};// 创建DOM对象
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 ? '&nbsp;': ''
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.book = null;
co.extend(this, this.setOptions(options));
// 创建框架结构
this.createStruct();
// 创建快照书签
co.browser.ie && this.saveBookMark();
};

解决方案 »

  1.   

    源码中部// 静态变量https://developer.mozilla.org/en/Rich-Text_Editing_in_Mozilla
    editor.NO_ARG_COMMAND = {
    BOLD: 'bold',
    ITALIC: 'italic',
    UNDERLINE: 'underline',
    CUT: 'cut',
    COPY: 'copy',
    JUSTIFYLEFT: 'justifyleft',
    JUSTIFYRIGHT: 'justifyright',
    JUSTIFYCENTER: 'justifycenter',
    INSERTUNORDEREDLIST: 'insertunorderedlist',
    INSERTORDEREDLIST: 'insertorderedlist',
    OUTDENT: 'outdent',
    INDENT: 'indent',
    REMOVEFORMAT: 'removeformat'
    };
    // 原型扩展
    editor.prototype = {
    setOptions: function(options) {
    this.options = {
    emotion: [
    { 'title': '微笑', 'pos': '-5px -5px',  'url': co.Root + 'o_220510752_p_r2_c2.gif' }, 
    { 'title': '大笑', 'pos': '-32px -5px', 'url': co.Root + 'o_220510752_p_r2_c3.gif' },
    { 'title': '窃笑', 'pos': '-59px -5px', 'url': co.Root + 'o_220510752_p_r2_c4.gif' },
    { 'title': '眨眼', 'pos': '-86px -5px', 'url': co.Root + 'o_220510752_p_r2_c5.gif' },
    { 'title': '吐舌', 'pos': '-113px -5px','url': co.Root + 'o_220510752_p_r2_c11.gif'},
    { 'title': '色色', 'pos': '-140px -5px','url': co.Root + 'o_220510752_p_r2_c6.gif' },
    { 'title': '呲牙', 'pos': '-168px -5px','url': co.Root + 'o_220510752_p_r2_c7.gif' },
    { 'title': '讨厌', 'pos': '-194px -5px','url': co.Root + 'o_220510752_p_r2_c8.gif' }
    ],
    baroverOpc: 0.7
    };
    return co.extend(this.options, options || {});
    },
    // 创建编辑器整个框架结构
    createStruct: function() {
    // 创建工具条
    this.createToolBar();
    // 创建隐藏textarea容器
    this.createTextArea();
    // 创建iframe容器
    this.createIframe();
    // 创建工具底栏
    this.createToolFoot();
    // 创建工具条遮盖层
    this.createToolLayer();
    },
    // 创建工具条
    createToolBar: function() {
    var _this = this;
    this.bar = co.append(this.container, 'div');
    this.bar.id = 'ebar'; this.bar.className = 'ebar';
    for(var i = 0, l = this.bardata.length; i < l; i++) {
    var sp = co.append(this.bar, 'span');
    co.setProperties(sp, this.bardata[i]);
    }
    // 事件代理
    this.bar.onmousedown = function(e) {
    var t = co.target(e), command = t['command'];
    if(t.tagName == 'SPAN') {
    if(!!command) {
    _this.changeSty(t, 'active'); // 切换样式
    if(command.toUpperCase() in editor.NO_ARG_COMMAND) { // 不需要参数的命令
    if(co.browser.firefox) { /* firefox暂不提供粘贴, 剪切, 复制功能 详见http://www.mozilla.org/editor/midasdemo/securityprefs.html*/
    if(command.toUpperCase() == 'CUT' || command.toUpperCase() == 'COPY') {
    alert('为了信息安全FF暂不提供该功能');
    return false;
    }
    }
    _this.doEditCommand(command);
    _this.ifr.contentWindow.focus(); // 焦点要记住
    } else {
    switch(command) {  // 代理分支 
    case 'fontSize': // 字号
    case 'fontName': // 字体
    case 'createLink': // 创建连接
    case 'insertImage': // 插入图片
    case 'insertEmotion': // 插入表情
    case 'insertHTML': // 插入表格
    _this.setPopInit(command, t /*被点击的控件*/); /* 需要pop类弹窗的公用初始化方法 */
    break;
    case 'foreColor': // 颜色
    _this.setFontColor(command, t);
    break;
    case 'autoLay': // 自动排版
    _this.autoLay();
    break;
    default:
    alert('没有提供此项功能');
    break;
    }
    }
    }
    }
    };
    // 样式切换
    this.bar.onmouseup = function(e) { _this.changeSty(co.target(e), 'curr'); };
    this.bar.onmouseover = function(e) { _this.changeSty(co.target(e), 'hover'); };
    this.bar.onmouseout = function(e) { _this.changeSty(co.target(e), 'curr'); };
    },
    // 样式切换
    changeSty: function(t, sign) {
    if(t.tagName == 'SPAN') {
    if(sign == 'curr') {
    t.className = this.bardata[t['index']]['class'];
    this.currActive = null;
    } else {
    if(!!this.currActive) {
    this.currActive.className =  this.bardata[this.currActive['index']]['class'];

    t.className = 'tag ' +  this.bardata[t['index']][sign];
    this.currActive = t;
    }
    }
    }, // 抽象需要弹窗功能的公用接口
    setPopInit: function(command, tar) {
    var cfg = '', _body = '', _td = '', S = '';
    if(command == 'fontSize') {
    cfg = {
    'id': 'fscon',
    'title': '字号',
    'container': 'fscon',
    'concss': 'fsn',
    'heacss': 'fshead',
    'bodcss': 'fsbody',
    'chicss': ['bas f1', 'bas f2', 'bas f3', 'bas f4', 'bas f5', 'bas f6', 'bas f7'],
    'content': ['字号1', '字号2', '字号3', '字号4', '字号5', '字号6', '字号7']
    };
    for(var i = 0, l = cfg.content.length; i < l; i++) {
    _body += '<a class="' + cfg.chicss[i] + '" href="javascript:void(0);">' + cfg.content[i] + '</a>';
    }
    }
    if(command == 'fontName') {
    cfg = {
    'id': 'ffcon',
    'title': '字体',
    'container': 'ffcon',
    'concss': 'fsn',
    'heacss': 'fshead',
    'bodcss': 'fsbody',
    'chicss': ['bas', 'bas', 'bas', 'bas', 'bas', 'bas', 'bas', 'bas', 'bas'],
    'content': ['宋体', '黑体', '楷体', '隶书', '幼圆', 'Arial', 'Georgia', 'Verdana', 'Helvetica']
    };
    for(var i = 0, l = cfg.content.length; i < l; i++) {
    _body += '<a class="' + cfg.chicss[i] + '" href="javascript:void(0);">' + cfg.content[i] + '</a>';
    }
    }
    if(command == 'createLink' || command == 'insertImage' || command == 'insertEmotion') { // 创建链接 + 插入图片 + 插入表情形体类似. 只需要单独定制id和title即可
    cfg = {'container':'flcon', 'concss':'fsn', 'heacss':'fshead', 'bodcss':'fsbody'};
    if(command == 'createLink') { cfg.title = '插入链接'; /*title*/cfg.id = 'fflink';/*容器id*/cfg.txtId = 'lurl'; /*文本框id*/cfg.cofbtnId = 'lkcof';/* 确认按钮*/cfg.celbtnId = 'lkcel';}/*撤销按钮*/
    if(command == 'insertImage') { cfg.title = '插入图片';cfg.id = "ffimage";cfg.txtId = 'limg';cfg.cofbtnId = 'imcof';cfg.celbtnId = 'imcel';} 
    if(command == 'insertEmotion') { cfg.title = '插入表情';cfg.id = "ffemotion";cfg.container="emotionCon"; }
    if(command == 'createLink' || command == 'insertImage') {
    _body += '<div style="padding:7px;background-color:#FFF;font-size:12px;" unselectable="on"><span>链接地址</span>';
    _body += '<input type="text" id="' + cfg.txtId + '" style="width:200px;" /></div>';
    _body += '<div style="text-align:center;">'
    _body += '<img id="' + cfg.cofbtnId + '" style="padding-right:10px;" src="'+co.Root+'o_220836549.p.gif" />';
    _body += '<img id="' + cfg.celbtnId + '" src="'+co.Root+'o_220726721.p.gif" /></div>';
    }
    if(command == 'insertEmotion') {
    for(var i = 0, l = this.emotion.length; i < l; i++) {
    S += ';background-position:' + this.emotion[i]['pos'] + ';width:21px;height:21px;'
    _td += '<td unselectable="on" url="'+this.emotion[i].url+'" title='+this.emotion[i]['title']+' style="cursor:pointer;background-image:url('+co.Root+'o_220510752_p.gif)'+S+'"></td>';
    }
    _body += '<table><tr>'+ _td +'</tr></table>';
    }
    }
    if(command == 'insertHTML') {
    cfg = {
        'id':'fftable','title':'插入表格','container':'isbtlCon','concss':'fsn','heacss':'fshead',
            'bodcss':'fsbody','rowId':'rowtxt','cellId':'celltxt','cfmId':'tblcfm','celId':'tblcel',
    'tblwId':'tblwid','tblhId':'tblhid'
      };
    _body += '<div class="tblCon">行数<input type="text" id="'+cfg.rowId+'" class="tblTxt" />列数<input type="text" id="'+cfg.cellId+'" class="tblTxt" /></div>';
    _body += '<div class="tblCon">表格的宽度<input type="text" id="'+cfg.tblwId+'" class="tblTxt" />px</div>';
    _body += '<div class="tblCon">表行的高度<input type="text" id="'+cfg.tblhId+'" class="tblTxt" />px<div class="tblbtn">';
    _body += '<img id="'+cfg.cfmId+'" style="padding-right:6px;" src="'+co.Root+'o_220836549.p.gif" />';
    _body += '<img id="'+cfg.celId+'" src="'+co.Root+'o_220726721.p.gif" /></div></div>';
    }
    this.setPopRun(command, cfg, cfg.title, tar, _body);
    },
      

  2.   

    源码下部 // 实现POP弹窗的所有功能
    setPopRun: function(command, cfg, title, tar/* 点击的控件 */, content/* POP弹窗的body内容 */) {
    var _this = this;
    var fwin = newFactory.create(popUp.create, cfg, content);
    _this.fixPop(fwin, tar); // 定位弹窗
    if(title == '插入链接' || title == '插入图片') { /* 插入链接和插入图片需要特殊定制 */
    co.getId(cfg.cofbtnId).onclick = function() { // 此处不用addEvent添加事件.避免多次绑定
    var _val = co.getId(cfg.txtId).value;
    if(_val.length == 0) _val = ' '; // IE下链接可以为空.但其他最起码有一个空格.否则报错
    _this.doEditCommand(command, _val);
    co.getId(cfg.id).style.display = "none"; 
    }; //确认
    co.getId(cfg.celbtnId).onclick = function() { co.getId(cfg.id).style.display = "none"; }
    }
    if(title == '插入表格') {
    co.getId(cfg.cfmId).onclick = function() {
    var _html = _this.createTblHtml(cfg);
    if(!co.browser.ie) { // IE不支持insertHTML
    _this.doEditCommand(command, _html);
    } else {
    _this.ifr.contentWindow.focus(); // 注意IE下 focus问题
    _this.doc.selection.createRange().pasteHTML(_html);
    }
    co.getId(cfg.id).style.display = 'none';
    };
    co.getId(cfg.celId).onclick = function() { co.getId(cfg.id).style.display = 'none'; }
    }
    _this.hidePop(fwin, title); // bind隐藏弹窗
    fwin.onclick = function(e) {
    var t = co.target(e);
    if(title == '插入链接' || title == '插入图片' || title == '插入表格') { co.cancelBubble(e); } // 插入链接和图片禁止冒泡
    if(t.tagName == 'A') { /* 字号和字体 */
    _this.doEditCommand(command, command == 'fontSize' ? t.innerHTML.slice(-1) : t.innerHTML);
    } else if(t.tagName == 'TD') { /* 表情 */
    _this.doEditCommand('insertImage', t.getAttribute('url'));
    }
    };
    },
    // 设置字体颜色 
    setFontColor: function(command, tar) {
    var _this = this;
    var fwin = newFactory.create(ColorPicker.create, {'id':'colorPicker'});
    _this.fixPop(fwin, tar); // 定位弹窗
    _this.hidePop(fwin, '文字颜色');
    co.addEvent(fwin, 'click', function(e) {
    var t = co.target(e);
    if(!!t.title) {
    _this.doEditCommand(command, t.title);
    }
    });
    },
    // 自动排版
    autoLay: function() {
    var _child = this.doc.body.childNodes;
    for(var i = 0, l = _child.length; i < l; i++){
    if(_child[i].tagName == 'DIV' || _child[i].tagName == 'P') {
    _child[i].style.textIndent = _child[i].style.textIndent == '2em' ? '' : '2em'; // text-indent属性
    }
    }
    },
    // 生成Table的HTML
    createTblHtml: function(cfg) {
    var _rownum = co.getId(cfg.rowId).value, _cellnum = co.getId(cfg.cellId).value,
    _tblwid = co.getId(cfg.tblwId).value, _tblhei = co.getId(cfg.tblhId).value;
    var _html = '<table border="1" width="'+_tblwid+'">';
    for(var i = 0; i < parseInt(_rownum,10); i++) { // 行
    _html += '<tr height="'+_tblhei+'">';
    for(var j = 0; j < parseInt(_cellnum,10); j++) { // 列
    _html += '<td></td>';
    }
    _html += '</tr>';
    }
    _html +='</table>';
    return _html;
    },
    // 保存快照用于IE定位
    saveBookMark: function() {
    var _this = this;
    co.addEvent(_this.ifr, 'beforedeactivate', function() {
    var rng = _this.doc.selection.createRange();
    if(rng.getBook) {
    _this.book = _this.doc.selection.createRange().getBook(); // 保存光标用selection下的createRange();
    }
    });
    co.addEvent(_this.ifr, 'activate', function() {
    if(_this.book) {
    // Moves the start and end points of the current TextRange object to the positions represented by the specified book.
    // 将光标移动到 TextRange 所以需要用 body.createTextRange();
    var rng = _this.doc.body.createTextRange();
    rng.moveToBook(_this.book);
    rng.select();
    _this.book = null;
    }
    });
    },
    // 定位弹窗 
    fixPop: function(fwin, tar) {
    co.setProperties(fwin, {'style': 'top:' + (co.getPos(tar).y + tar.offsetHeight) + 'px; left:' + co.getPos(tar).x + 'px' });
    },
    // 隐藏弹窗
    hidePop: function(fwin, title) {
    co.addEvent(document, 'click', function(e) {
    var t = co.target(e);
    fwin.style.display = t.title == title ? 'block' : 'none';
    });
    co.addEvent(this.doc, 'click', function(e) { fwin.style.display = 'none'; }); /* 注意:绑定iframe事件句柄需要用W3C接口(addEventListener) */
    },
    // 执行命令
    doEditCommand: function(name, arg) {
    try {
    this.ifr.contentWindow.focus(); // 放置焦点要操作contentWindow
    this.doc.execCommand(name, false, arg);
    } catch(e) {}
    },
    // 创建隐藏文本域
    createTextArea: function() {
    this.txtarea = co.append(this.container, 'textarea');
    this.txtarea.id='bgcode'; this.txtarea.style.display = 'none';
    },
    // 创建空白iframe
    createIframe: function() {
    var _this = this;
    this.ifr = co.append(this.container, 'iframe', {'frameborder': 0, 'style': 'border:0; vertical-align:bottom', 'class': 'econtent' });
    this.doc =  this.ifr.contentDocument || this.ifr.contentWindow.document; // W3C || IE
    this.doc.designMode = 'on';
    this.doc.open();
    // margin为了消除iframe中的html上部的空白
    this.doc.write('<html><head><style>body{ margin:3px; word-wrap:break-word; word-break: break-all; }</style></head><body>GoodNessEditor</body></html>');
    this.ifr.contentWindow.focus();
    this.doc.close();
    // 当iframe失去焦点.偷偷将代码存入textare中
    co.addEvent(this.ifr.contentWindow, 'blur', function() {
    _this.txtarea.value = _this.doc.body.innerHTML;
    });
    },
    // 创建编辑器底部
    createToolFoot: function() {
    var _this = this;
    co.append(this.container, 'div', 'efoot').innerHTML = '<input type="checkbox" id="showCode" /><label for="showCode">显示源码</label>';
    // 绑定显示源码事件
    co.getId('showCode').onclick = function() { 
    if(this.checked) {
    _this.layer.style.display = 'block';
    co.getId('bgcode').style.display = 'block';
    _this.ifr.style.display = 'none';
    } else {
    _this.layer.style.display = 'none';
    co.getId('bgcode').style.display = 'none';
    _this.doc.body.innerHTML = co.getId('bgcode').value;
    _this.ifr.style.display = 'block';
    }
    };
    },
    // 创建工具栏遮盖层
    createToolLayer: function() {
    this.layer = co.setProperties(
    co.append(document.body,'div'), 
    {
    'style':'width:'+this.bar.offsetWidth+'px;height:'+this.bar.offsetHeight+'px;background-color:#fff;position:absolute;display:none'
    }
    );
    co.setOpacity(this.layer, this.baroverOpc);
    this.layer.style.left = co.getPos(this.bar).x + 'px';
    this.layer.style.top = co.getPos(this.bar).y + 'px';
    }
    };
    谢谢大家支持.实践就一定会进步.我的自学历程
    1. 日期联动 
    http://topic.csdn.net/u/20091215/11/3e361cb7-6437-456c-b9ea-b1122401f9ff.html[/url]
    2. 简易日历
    [url=http://topic.csdn.net/u/20100112/09/1eb255f6-6309-470d-9a6b-452398c7ec13.html

    3. 图片切换
    http://topic.csdn.net/u/20100114/09/7fdec7f6-6e42-4b00-8a5f-224e3ebdbec4.html
    4. 漂浮广告
    http://topic.csdn.net/u/20100320/20/34b6df08-1a01-4873-860a-f71d11639b1f.html
    5. 富文本编辑器
    http://topic.csdn.net/u/20100326/09/e244939b-36f4-42f5-a69c-9f8f81ced1eb.html?82811
      

  3.   

    不错不错,来jf了,LZ加油
    话说,怎么只有事件绑定没有取消啊。
      

  4.   

    msie: /msie/.test(ua) && !/opera/.test(ua),问下:为什么要加后面半句?
      

  5.   

    因为opera尤其以前版本 只要通过工具栏的简单设置就可以模拟IE firefox的UA 所以为了防止伪装 就给他剔除.但最近版本比如我现在用的opera10就没那么容易了.以前的样式可以参考下:http://www.davidtan.org/how-to-change-opera-user-agent-string/
      

  6.   


    哦,有那个必要么?用傲游还可以自定义了,他要设置成firefox的userAgent怎么办?
      

  7.   

    这个还是看个人的想法了.因为通过UA本身就不是最准备的判断方式. 如果不考虑伪装那么就不需要了.
    至于你说的firefox 是因为那段代码firefox的判定是在opera之后得.所以在之前就一定确定为opera了就已经break了.把IE判定放在最前是因为ie基本是最常用的.不知道我说清楚了没.
      

  8.   

    [菜鸟自学五]富文本编辑器 [JavaScript]
      

  9.   

    那里还用ua来判断 ?OPERA本身有WINDOW.OPERA你不用假如按你的判断,如果是别人将ua设为ie的了,你这样判断,就不是列表中的浏览器了吧,
    这样有可能导致一个根据浏览器的分支来执行的 语句根本没有执行的 机会了吧另
    如果ua是firefox了,oprea还怎么break????
      

  10.   

    唉 我说你想要准备喷 也要把知识储备好再说吧. 我给你举个例子你看啊:
    Opera伪装IE后的UA串为:
    Mozilla/4.0 (compatible; MSIE6.0; Windows NT 5.1) Opera 7.54
    伪装成FF也是类似
    所以当for in循环 检测到有Opera字样那么就break 确定为Opera浏览器了 那么就排除了伪装.至于我用什么判断 那个是有根据和有个人需求 如果你觉得就window.Opera是你的牛逼法宝 那么你用
    跟我完全没关系. 你这么牛 也不需要来跟我这种菜鸟来讨论这么低级别的东西.很多书都讲了UA判断 和特性判断的区别和用途 你可以自己翻书看.
      

  11.   

    不错 楼主顶了http://www.ggsccn.com/
      

  12.   

    a人生- CSDN社区 ... 
      

  13.   

    ASP.NET交流群(54017195)欢迎您的加入!
    高手聚集,有你更精彩!
      

  14.   

    没看过什么 js的书,只是有点疑问才问的,没想到得罪lz了,哎,