根据网上搜集的编辑器资料,整理了一份相对完整的编辑器代码,我是用来制作CMS模版编辑器的,现在将CMS代码部分去掉了。
源代码下载:editor.js
【Javascript源代码】
![ContractedBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
/* 添加事件 */
var addEventHandler = function (oTarget, sEventType, fnHandler) {
romoveEventHandler(oTarget, sEventType, fnHandler);
if (oTarget.addEventListener) {
oTarget.addEventListener(sEventType, fnHandler, false );
} else if (oTarget.attachEvent) {
oTarget.attachEvent( " on " + sEventType, fnHandler);
} else {
oTarget[ " on " + sEventType] = fnHandler;
}
}
/* 注销事件 */
var romoveEventHandler = function (oTarget, sEventType, fnHandler) {
if (oTarget.removeEventListener) {
oTarget.removeEventListener(sEventType, fnHandler, false );
} else if (oTarget.detachEvent) {
oTarget.detachEvent( " on " + sEventType, fnHandler);
} else {
oTarget[ " on " + sEventType] = "" ;
}
}
function editor(){
var ieRange = false ;
var edit = document.createElement( " iframe " );
edit.style.width = " 500px " ;
edit.style.height = " 300px " ;
edit.frameBorder = 1 ;
document.getElementsByTagName( " body " )[ 0 ].appendChild(edit);
var win = edit.contentWindow;
var doc = win.document;
var _saveRange = function (){ // IE下保存Range对象
if ( !! document.all &&! ieRange){ // 是否IE并且判断是否保存过Range对象
var sel = doc.selection;
ieRange = sel.createRange();
if (sel.type != ' Control ' ){ // 选择的不是对象
var p = ieRange.parentElement(); // 判断是否在编辑器内
if (p.tagName == " INPUT " || p == document.body)ieRange = false ;
}
}
}
var _insert = function (text) { // 插入替换字符串
if ( !! ieRange) {
ieRange.pasteHTML(text);
ieRange.select();
ieRange = false ; // 清空下range对象
} else { // 焦点不在html编辑器内容时
win.focus();
if (document.all) {
doc.body.innerHTML += text; // IE插入在最后
} else { // Firefox
var sel = win.getSelection();
rng.insertNode(frg);
}
}
}
var _ieEnter = function (){ // IE回车修改
var e = win.event;
if (e.keyCode == 13 ){
_saveRange();
_insert( " <br/> " );
return false ;
}
}
var _fnPaste = function (e){
e.returnValue = false ;
var shtml = window.clipboardData.getData( " Text " ); // 安全起见,只取纯文本
_saveRange();
_insert(shtml); // 把文本粘贴进iframe
}
if (document.all){
addEventHandler(edit, " load " , function (){ // 绑定编辑器粘帖事件onpaste;
with (doc.getElementsByTagName( " body " )[ 0 ]){
addEventHandler(doc.getElementsByTagName( " body " )[ 0 ], " paste " , function (event){
}
});
}
doc.designMode = ' On ' ; // 可编辑
doc.contentEditable = true ;
// 但是IE与FireFox有点不同,为了兼容FireFox,所以必须创建一个新的document。
doc.open();
var headHTML = ' <head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" />';
doc.writeln( ' <html> ' + headHTML + ' <body></body></html> ' );
doc.close();
// IE回车输出<br> 与 FF 统一;
if (document.all)doc.onkeypress = function (){ return _ieEnter()};
win.focus();
}
window.onload = editor;
【代码说明】
开启iframe的编辑模式的代码是doc.designMode='On',但是在Firefox下面单单这样仍然无法开始编辑模式,需要在iframe内创建一个新的document,同时可以通过这个方法来重定义编辑器内的样式兼容。代码如下:
doc.contentEditable = true ;
// 但是IE与FireFox有点不同,为了兼容FireFox,所以必须创建一个新的document。
doc.open();
var headHTML = ' <head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> ' ;
var headHTML =headHTML+ ' <style>*{margin:0;padding:0;font:12px;}</style> ' ;
var headHTML =headHTML+ ' </head> ' ;
doc.writeln( ' <html> ' + headHTML + ' <body></body></html> ' );
doc.close();
在IE下面回车时,编辑器会自动添加<p>标签,而在firefox下则是<br>,因此为了做到一致,同时考虑做模版编辑器时代码的转换方便,我这里统一为回车输入<br>,代码如下:
var e = win.event;
if (e.keyCode == 13 ){
_saveRange(); // 获取光标焦点
_insert( " <br/> " ); // 插入<br/>
return false ;
}
}
另一个IE下头痛的问题就是粘帖进去的内容如果是像<a href="http://www.xx.com"></a>这样,编辑器就会自带超链接,这在模板编辑器里是需要花大量正则去替换。因此为了一劳永逸以及方便,我的做法是在粘帖事件上进行处理,给iframe里的body添加onpaste事件。
添加onpaste事件很简单,只要在iframe内的body添加就行,但是如果直接添加的话,会失败,看了网上的代码,我的理解是当添加事件的时候element并未生成,需要等iframe加载完毕才有效果。
window.clipboardData.getData("Text");的作用就是将粘帖的内容转换成纯文本。
代码如下:
e.returnValue = false ;
var shtml = window.clipboardData.getData( " Text " ); // 安全起见,只取纯文本
_saveRange();
_insert(shtml); // 把文本粘贴进iframe
}
if (document.all){
addEventHandler(edit, " load " , function (){ // 绑定编辑器粘帖事件onpaste;
with (doc.getElementsByTagName( " body " )[ 0 ]){
addEventHandler(doc.getElementsByTagName( " body " )[ 0 ], " paste " , function (event){
_fnPaste(event);
});
}
});
}
PS:如有疑问,可留言。