整理的一份iframe编辑器代码

根据网上搜集的编辑器资料,整理了一份相对完整的编辑器代码,我是用来制作CMS模版编辑器的,现在将CMS代码部分去掉了。

源代码下载:editor.js

【Javascript源代码】

Javascript Code
// JavaScript Document
/*
添加事件*/
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();
         var rng = sel.getRangeAt(0);
         var frg = rng.createContextualFragment(text);
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){
            _fnPaste(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" />';
  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回车输出<br> 与 FF 统一;
if(document.all)doc.onkeypress = function(){return _ieEnter()};

win.focus();
}

window.onload
=editor;

【代码说明】

开启iframe的编辑模式的代码是doc.designMode='On',但是在Firefox下面单单这样仍然无法开始编辑模式,需要在iframe内创建一个新的document,同时可以通过这个方法来重定义编辑器内的样式兼容。代码如下: 

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" />';
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 _ieEnter=function(){//IE回车修改
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");的作用就是将粘帖的内容转换成纯文本。
代码如下:

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){
_fnPaste(event);
       });
}
});
}

PS:如有疑问,可留言。

posted on 2011-03-23 12:40  Lecaf  阅读(3737)  评论(6编辑  收藏  举报