整理的一份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 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){
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" />';
}
});
}
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;
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();
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;
}
}
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);
});
}
});
}
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:如有疑问,可留言。