自己写的兼容ie和ff的在线文本编辑器类似ewebeditor


Posted in Javascript onDecember 12, 2012

怎么说呢,刚包完夜吧,应该很累了,但现在仍有力气敲打着这些字符,看来我还没有到此为止啊。
废话少说,最近写了个在线的编辑器,类似ewebeditor那样的,当然没有人家那么强大,但是基本功能都有,而且还是兼容ie和ff的,为此我也花了不少功夫,还是赶紧把代码祭出来吧
demo.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> 
</head> 
<body> 
<script src="core.js"></script> 
<script src="advance.js"></script> 
<table border="0" width="800" height="500" bgcolor="gray"> 
<tr height="50"><td> 
字体:<select onchange="FontName(this.options[this.selectedIndex].value)"> 
<option value="宋体">宋体 
<option value="黑体">黑体 
<option value="楷体_GB2312">楷体 
<option value="仿宋_GB2312">仿宋 
<option value="隶书">隶书 
<option value="幼圆">幼圆 
<option value="新宋体">新宋体 
<option value="细明体">细明体 
<option value="Arial">Arial 
<option value="Arial Black">Arial Black 
<option value="Arial Narrow">Arial Narrow 
<option value="Bradley Hand ITC">Bradley Hand ITC 
<option value="Brush Script MT">Brush Script MT 
<option value="Century Gothic">Century Gothic 
<option value="Comic Sans MS">Comic Sans MS 
<option value="Courier">Courier 
<option value="Courier New">Courier New 
<option value="MS Sans Serif">MS Sans Serif 
<option value="Script">Script 
<option value="System">System 
<option value="Times New Roman">Times New Roman 
<option value="Viner Hand ITC">Viner Hand ITC 
<option value="Verdana">Verdana 
<option value="Wide Latin">Wide Latin 
<option value="Wingdings">Wingdings</option> 
</select> 
字号:<select onchange="FontSize(this.options[this.selectedIndex].value)"> 
<option value="1">1</option> 
<option value="2">2</option> 
<option value="3">3</option> 
<option value="4">4</option> 
<option value="5">5</option> 
<option value="6">6</option> 
<option value="7">7</option> 
</select> 
<button onclick="color()">颜色</button> 
<button onclick="bold()">加粗</button> 
<button onclick="italic()">倾斜</button> 
<button onclick="left()">居左</button> 
<button onclick="center()">居中</button> 
<button onclick="right()">居右</button> 
</td></tr> 
<tr height="50"><td> 
<button>插入影视和图片</button> 
<button>上传文件</button> 
<button onclick="inserttable()">插入表格</button> 
<button onclick="inserthr()">插入水平线</button> 
<button onclick="insertlink()">插入超链接</button> 
</td></tr> 
<tr height="400"> 
<td height="400"> 
<iframe id="content" width="100%" height="100%"></iframe> 
</td> 
</tr> 
</table> 
<script src="edit.js"></script> 
</body> 
</html>

core.js
sx={}; 
sx.comm={}; 
sx.comm.string=function(){ 
if(!String.prototype.left){ 
String.prototype.left=function(l){ 
return this.substr(0,l); 
} 
} 
if(!String.prototype.right){ 
String.prototype.right=function(l){ 
return this.substr(this.length-l,l); 
} 
} 
if(!String.prototype.trim){ 
String.prototype.trim=function(){ 
return this.replace(/^/s+|/s+$/g,""); 
} 
} 
}(); 
sx.comm.array=function(){ 
if(!Array.prototype.indexOf){ 
Array.prototype.indexOf=function(data){ 
for(var i=0;i<this.length;i++){ 
if(this[i]==data){ 
break; 
} 
} 
return i==this.length?-1:i; 
} 
} 
if(!Array.prototype.lastIndexOf){ 
Array.prototype.lastIndexOf=function(data){ 
for(var i=this.length-1;i>=0;i--){ 
if(this[i]==data){ 
break; 
} 
} 
return i; 
} 
} 
if(!Array.prototype.clone){ 
Array.prototype.clone=function(){ 
var temp=[]; 
for(var i=0;i<this.length;i++){ 
if(this[i] instanceof Array){ 
temp[i]=this[i].clone(); 
}else{ 
temp[i]=this[i]; 
} 
} 
return temp; 
} 
} 
if(!Array.prototype.every){ 
Array.prototype.every=function(o,f){ 
for (var i = 0; i < this.length; i++) { 
if (this[i] instanceof Array) { 
this[i].every(o,f); 
} 
else { 
f.call(o, this[i]); 
} 
} 
} 
} 
}(); 
sx.comm.ver=function(){ 
try{ 
HTMLElement; 
return "ff"; 
}catch(e){ 
return "ie"; 
} 
}(); 
sx.comm.ext=function(){ 
if(sx.comm.ver=="ff"){ 
HTMLElement.prototype.__defineGetter__("outerHTML",function(){ 
var attr; 
var attrs=this.attributes; 
var str="<"+this.tagName.toLowerCase(); 
for(var i=0;i<attrs.length;i++){ 
attr=attrs[i]; 
if(attr.specified) 
str+=" "+attr.name+'="'+attr.value+'"'; 
} 
if(!this.canHaveChildren) 
return str+">"; 
return str+">"+this.innerHTML+"</"+this.tagName.toLowerCase()+">"; 
}); 
HTMLElement.prototype.__defineGetter__("canHaveChildren",function(){ 
switch(this.tagName.toLowerCase()){ 
case "area": 
case "base": 
case "basefont": 
case "col": 
case "frame": 
case "hr": 
case "img": 
case "br": 
case "input": 
case "isindex": 
case "link": 
case "meta": 
case "param": 
return false; 
} 
return true; 
}); 
XMLDocument.prototype.selectNodes = Element.prototype.selectNodes = function (){ 
//alert(arguments[0]); 
var oNSResolver = this.createNSResolver(this.documentElement) 
var aItems = this.evaluate(arguments[0].toLowerCase(), this, oNSResolver, 
XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null) 
var aResult = []; 
for( var i = 0; i < aItems.snapshotLength; i++) 
{ 
aResult[i] = aItems.snapshotItem(i); 
} 
//alert(aItems.snapshotLength); 
return aResult; 
} 
} 
}(); 
sx.event={}; 
sx.event.target=function(){ 
if(window.event){ 
return window.event.srcElement; 
}else{ 
var f=arguments.callee.caller; 
while(f){ 
if(f.arguments[0] instanceof Event){ 
return f.arguments[0].target; 
} 
f=f.caller; 
} 
} 
} 
sx.event.event=function(){ 
if (window.event) { 
return window.event; 
}else{ 
var f=arguments.callee.caller; 
while (f) { 
if (f.arguments[0] instanceof Event) { 
return f.arguments[0]; 
} 
f = f.caller; 
} 
} 
} 
sx.event.relatedtarget=function(){ 
if(window.event){ 
if(window.event.type=="mouseover"){ 
return window.event.fromElement; 
}else if(window.event.type=="mouseout"){ 
return window.event.toElement; 
} 
}else{ 
var f=arguments.callee.caller; 
while (f) { 
if (f.arguments[0] instanceof Event) { 
return f.arguments[0].relatedTarget; 
} 
f = f.caller; 
} 
} 
} 
sx.event.stopevent=function(){ 
if (window.event) { 
window.event.returnValue=false; 
window.event.cancelBubble=true; 
}else{ 
var f=arguments.callee.caller; 
while(f){ 
if(f.arguments[0] instanceof Event){ 
break; 
} 
f=f.caller; 
} 
f.arguments[0].preventDefault(); 
f.arguments[0].stopPropagation(); 
} 
} 
sx.event.addevent=function(e,t,f){ 
if(!arguments.callee.event){ 
arguments.callee.event=[]; 
} 
if(e.attachEvent){ 
e.attachEvent("on"+t,f); 
}else{ 
e.addEventListener(t,f,false); 
} 
arguments.callee.event.push(f); 
return arguments.callee.event.length-1; 
} 
sx.event.removeevent=function(e,t,i){ 
if(e.detachEvent){ 
e.detachEvent("on"+t,sx.event.addevent.event[i]); 
}else{ 
e.removeEventListener(t,sx.event.addevent.event[i],false); 
} 
sx.event.addevent.event[i]=null; 
} 
sx.event.parseevent=function(e,t){ 
if (sx.comm.ver=="ie"){ 
e.fireEvent("on"+t); 
}else{ 
var evt = document.createEvent("Events"); 
evt.initEvent(t, true, true); 
e.dispatchEvent(evt); 
} 
} 
sx.dom={}; 
sx.dom.text=function(e){ 
return this.e.innerText?this.e.innerText:this.e.innerHTML.replace(//<.*?/>/igm,""); 
} 
sx.dom.elementnodes=function(e,flag){ 
var temp=[]; 
var a=e.childNodes; 
for(var i=0;i<a.length;i++){ 
if(a[i].nodeType==flag){ 
temp.push(a[i]); 
} 
} 
return temp; 
} 
sx.dom.elementallnodes=function(e,flag){ 
var temp=[]; 
var a=e.getElementsByTagName("*"); 
for(var i=0;i<a.length;i++){ 
if(a[i].nodeType==flag){ 
temp.push(a[i]); 
} 
} 
return temp; 
} 
sx.dom.xpath=function(e,mode){ 
p=e.cloneNode(true); 
var s=p.getElementsByTagName("script"); 
for(var i=0;i<s.length;i++) 
p.replaceChild(s[i].cloneNode(false),s[i]); 
var html=p.outerHTML.replace(//=(?!"|')(.*?)(?=/s|>)/ig,"=/"$1/""); 
if(window.ActiveXObject){ 
var x=new ActiveXObject("Msxml2.DOMDocument"); 
x.async=false; 
x.loadXML("<?xml version=/"1.0/" encoding=/"gb2312/" ?>"+html); 
}else{ 
var oParser = new DOMParser(); 
//alert(html); 
var x = oParser.parseFromString(html,"text/xml"); 
//alert(x.documentElement.tagName); 
} 
var div=x.selectNodes(mode); 
//alert(div.length); 
var temp=[]; 
var a1=x.selectNodes(e.tagName.toUpperCase()+"//*"); 
//alert(a1.length); 
var all=e.getElementsByTagName("*"); 
//alert(all.length); 
var i1=0; 
for(i=0;i<a1.length;i++){ 
//alert(i); 
if(a1[i]==div[i1]){ 
temp.push(all[i]); 
i1++; 
} 
} 
x=null; 
return temp; 
} 
sx.dom.left=function(e){ 
if(document.getBoundingClientRect){ 
return e.getBoundingClientRect().left; 
}else{ 
var a=e; 
var left=0; 
while(a){ 
left+=a.offsetLeft; 
a=a.offsetParent; 
} 
return left; 
} 
} 
sx.dom.top = function(e){ 
if(document.getBoundingClientRect){ 
return e.getBoundingClientRect().top; 
}else{ 
var a=e; 
var top=0; 
while(a){ 
top+=a.offsetTop; 
a=a.offsetParent; 
} 
return top; 
} 
} 
sx.dom.getstyle=function(e,prop){ 
if(e.currentStyle){ 
return e.currentStyle[prop]; 
}else{ 
return document.defaultView.getComputedStyle(e,null).getPropertyValue(prop); 
} 
} 
sx.dom.setstyle=function(e,data){ 
for(var i in data){ 
e.style[i]=data[i]; 
} 
} 
advance.js: 
var $=function(id){ 
return document.getElementById(id); 
}

edit.js
var w=$("content").contentWindow; 
w.document.designMode="on"; 
w.document.open(); 
w.document.write("<html><body bgcolor='white'></body></body>") 
w.document.close(); 
if(sx.comm.ver=="ie"){ 
//w.document.body.style.lineHeight="10px"; 
} 
w.document.onkeydown=function(){ 
if(sx.comm.ver=="ie"){ 
if(w.event.keyCode==13){ 
var s=w.document.selection.createRange(); 
s.pasteHTML("<br/>"); 
w.focus(); 
return false; 
} 
} 
} 
function wnd(){ 
var main=document.createElement("div"); 
sx.dom.setstyle(main,{ 
position:"absolute", 
width:"100%", 
height:"100%", 
backgroundColor:"lightblue", 
filter:"alpha(opacity=50)", 
opacity:0.5 
}); 
var body=document.createElement("div"); 
sx.dom.setstyle(body,{ 
position:"absolute", 
width:"200px", 
height:"250px", 
backgroundColor:"green", 
zIndex:1000 
}); 
var title=document.createElement("div"); 
sx.dom.setstyle(title,{ 
width:"200px", 
height:"20px", 
backgroundColor:"blue", 
}); 
var close=document.createElement("span"); 
sx.dom.setstyle(close,{ 
marginLeft:"180px", 
display:"block", 
width:"20px", 
height:"20px", 
textAlign:"center", 
cursor:"pointer" 
}); 
close.innerHTML="X"; 
close.onclick=function(){ 
main.parentNode.removeChild(main); 
body.parentNode.removeChild(body); 
} 
title.appendChild(close); 
body.appendChild(title); 
var content=document.createElement("div"); 
sx.dom.setstyle(content,{ 
width:"200px", 
height:"230px" 
}); 
body.appendChild(content); 
this.show=function(e){ 
document.body.appendChild(main); 
sx.dom.setstyle(main,{ 
top:"0px", 
left:"0px" 
}); 
document.body.appendChild(body); 
sx.dom.setstyle(body,{ 
top:sx.dom.top(e)+e.clientHeight+"px", 
left:sx.dom.left(e)+e.clientWidth+"px", 
}); 
} 
this.close=close; 
this.main=main; 
this.body=body; 
this.title=title; 
this.content=content; 
} 
function bold(){ 
w.document.execCommand("bold",null,null); 
} 
function italic(){ 
w.document.execCommand("italic",null,null); 
} 
function left(){ 
w.document.execCommand("JustifyLeft",null,null); 
} 
function center(){ 
w.document.execCommand("Justifycenter",null,null); 
} 
function right(){ 
w.document.execCommand("Justifyright",null,null); 
} 
function FontName(value){ 
w.document.execCommand("FontName", false, value); 
} 
function FontSize(value){ 
w.document.execCommand("FontSize", false, value); 
} 
function inserthr(){ 
if(document.selection){ 
w.focus(); 
var s=w.document.selection.createRange(); 
s.pasteHTML("<hr/>"); 
}else{ 
w.focus(); 
var s=w.getSelection().getRangeAt(0); 
s.insertNode(w.document.createElement("hr")); 
} 
} 
function insertlink(){ 
if (document.selection) { 
w.focus(); 
var s = w.document.selection.createRange(); 
} 
else { 
w.focus(); 
var s = w.getSelection().getRangeAt(0); 
} 
var e=sx.event.target(); 
var ww=new wnd(); 
ww.content.appendChild(document.createTextNode("请输入链接地址;")); 
var link=document.createElement("input"); 
link.type="text"; 
link.size=20; 
ww.content.appendChild(link); 
var b=document.createElement("button"); 
b.innerHTML="确定"; 
ww.content.appendChild(b); 
b.onclick=function(){ 
if(sx.comm.ver=="ie"){ 
s.pasteHTML("<a href='"+link.value+"'>"+s.htmlText+"</a>"); 
} 
else{ 
var a=w.document.createElement("a"); 
a.href=link.value; 
s.surroundContents(a); 
} 
sx.event.parseevent(ww.close,"click"); 
} 
ww.show(e); 
} 
function inserttable(){ 
if (document.selection) { 
w.focus(); 
var s = w.document.selection.createRange(); 
} 
else { 
w.focus(); 
var s = w.getSelection().getRangeAt(0); 
} 
var e=sx.event.target(); 
var ww=new wnd(); 
ww.content.appendChild(document.createTextNode("请输入行数;")); 
var tr=document.createElement("input"); 
tr.type="text"; 
tr.size=20; 
ww.content.appendChild(tr); 
ww.content.appendChild(document.createElement("br")); 
ww.content.appendChild(document.createTextNode("请输入列数;")); 
var td=document.createElement("input"); 
td.type="text"; 
td.size=20; 
ww.content.appendChild(td); 
ww.content.appendChild(document.createElement("br")); 
ww.content.appendChild(document.createTextNode("请输入单元格高度;")); 
var height=document.createElement("input"); 
height.type="text"; 
height.size=20; 
ww.content.appendChild(height); 
ww.content.appendChild(document.createElement("br")); 
ww.content.appendChild(document.createTextNode("请输入单元格宽度;")); 
var width=document.createElement("input"); 
width.type="text"; 
width.size=20; 
ww.content.appendChild(width); 
ww.content.appendChild(document.createElement("br")); 
var b=document.createElement("button"); 
b.innerHTML="确定"; 
ww.content.appendChild(b); 
b.onclick=function(){ 
var l1=Number(tr.value); 
var l2=Number(td.value); 
var h1=Number(height.value); 
var w1=Number(width.value); 
ww.content.appendChild(document.createTextNode("请输入单元格高度;")); 
var t=document.createElement("table"); 
t.border="1"; 
var tb=document.createElement("tbody"); 
t.appendChild(tb); 
for(var i=0;i<l1;i++){ 
var tr1=document.createElement("tr"); 
for(var i1=0;i1<l2;i1++){ 
var td1=document.createElement("td"); 
td1.innerHTML=""; 
sx.dom.setstyle(td1,{ 
width:w1+"px", 
height:h1+"px" 
}); 
tr1.appendChild(td1); 
} 
tb.appendChild(tr1); 
} 
if(sx.comm.ver=="ie"){ 
s.pasteHTML(t.outerHTML); 
} 
else{ 
s.insertNode(t); 
s.insertNode(document.createElement("br")); 
} 
sx.event.parseevent(ww.close,"click"); 
} 
ww.show(e); 
} 
function color(){ 
var e=sx.event.target(); 
if (document.selection) { 
w.focus(); 
var s = w.document.selection.createRange(); 
} 
else { 
w.focus(); 
var s = w.getSelection().getRangeAt(0); 
} 
var ww=new wnd(); 
var colors = ["00","33","66","99","CC","FF"]; 
var cp=document.createElement("span"); 
sx.dom.setstyle(cp,{ 
display:"inline-block", 
width:"10px", 
height:"10px", 
margin:"2px" 
}); 
for(var i1=5;i1>=0;i1--){ 
for(var i2=5;i2>=0;i2--){ 
for(var i3=5;i3>=0;i3--){ 
var cp1=cp.cloneNode(true); 
cp1.style.backgroundColor="#" + colors[i1] + colors[i2] + colors[i3]; 
cp1.title="#" + colors[i1] + colors[i2] + colors[i3]; 
cp1.onclick=function(){ 
if(sx.comm.ver=="ie"){ 
w.focus(); 
s.pasteHTML("<font color='"+this.title+"'>"+s.htmlText+"</font>"); 
} 
else{ 
var a=w.document.createElement("font"); 
a.color=this.title; 
s.surroundContents(a); 
} 
sx.event.parseevent(ww.close,"click"); 
} 
ww.content.appendChild(cp1); 
} 
} 
} 
ww.show(e); 
}

关键是demo.html和edit.js里的代码,core.js和advance.js里的代码是我为兼容浏览器写的,本想把它扩展成一个完善的框架的,因为时间有限,就没写下去了。

本编辑器还没有实现图片和文件的上传,因为需要服务器技术,所以我就没写了,可以交给读者慢慢研究。
我打算先将web放放了,开始专心于vc++的探究上,尽量能写出一个像样的程序出来,以后如果有时间我也会继续完善这个编辑器以及javascript兼容的框架。
恩,好好加油吧。

Javascript 相关文章推荐
用函数式编程技术编写优美的 JavaScript_ibm
May 16 Javascript
js和jquery对dom节点的操作(创建/追加)
Apr 21 Javascript
JavaScript实现两个Table固定表头根据页面大小自行调整
Jan 03 Javascript
jquery.post用法示例代码
Jan 03 Javascript
基于jquery固定于顶部的导航响应浏览器滚动条事件
Nov 02 Javascript
javascript使用prototype完成单继承
Dec 24 Javascript
jquery操作select元素和option的实例代码
Feb 03 Javascript
jQuery焦点图轮播插件KinSlideshow用法分析
Jun 08 Javascript
基于Vuejs和Element的注册插件的编写方法
Jul 03 Javascript
浅谈vue中关于checkbox数据绑定v-model指令的个人理解
Nov 14 Javascript
VUE脚手架的下载和配置步骤详解
Apr 01 Javascript
JavaScript设计模式之观察者模式与发布订阅模式详解
May 07 Javascript
用javascript模仿ie的自动完成类似自动完成功的表单
Dec 12 #Javascript
javascript实现图片切换的幻灯片效果源代码
Dec 12 #Javascript
javascript跑马灯悬停放大效果实现代码
Dec 12 #Javascript
javascript实现div的拖动并调整大小类似qq空间个性编辑模块
Dec 12 #Javascript
javascript采用数组实现tab菜单切换效果
Dec 12 #Javascript
javascript仿qq界面的折叠菜单实现代码
Dec 12 #Javascript
日历查询的算法 如何计算某一天是星期几
Dec 12 #Javascript
You might like
php Ajax乱码
2008/04/09 PHP
简单的移动设备检测PHP脚本代码
2011/02/19 PHP
PHP的pcntl多进程用法实例
2015/03/19 PHP
php 类自动载入的方法
2015/06/03 PHP
浅析Yii2 gridview实现批量删除教程
2016/04/22 PHP
PHP基于自定义类随机生成姓名的方法示例
2017/08/05 PHP
PHP大文件分割上传 PHP分片上传
2017/08/28 PHP
JS getMonth()日期函数的值域是0-11
2010/02/15 Javascript
JSON+JavaScript处理JSON的简单例子
2013/03/20 Javascript
JS 实现图片直接下载示例代码
2013/07/22 Javascript
js判断浏览器类型的方法
2013/08/07 Javascript
js获取IP地址的方法小结
2014/07/01 Javascript
JS命令模式例子之菜单程序
2016/10/10 Javascript
利用CSS、JavaScript及Ajax实现图片预加载的方法
2016/11/29 Javascript
详解angularjs利用ui-route异步加载组件
2017/05/21 Javascript
Javascript中将变量转换为字符串的三种方法
2017/09/19 Javascript
vue+Java后端进行调试时解决跨域问题的方式
2017/10/19 Javascript
vue实现图片加载完成前的loading组件方法
2018/02/05 Javascript
webpack 样式加载的实现原理
2018/06/12 Javascript
基于vue v-for 多层循环嵌套获取行数的方法
2018/09/26 Javascript
Vue使用lodop实现打印小结
2019/07/06 Javascript
Vue使用Clipboard.JS在h5页面中复制内容实例详解
2019/09/03 Javascript
Vue数据双向绑定底层实现原理
2019/11/22 Javascript
JS自定义对象创建与简单使用方法示例
2020/01/15 Javascript
python在指定目录下查找gif文件的方法
2015/05/04 Python
Pycharm 2019 破解激活方法图文详解
2019/10/11 Python
Python使用Tkinter实现滚动抽奖器效果
2020/01/06 Python
使用canvas对多图片拼合并导出图片的方法
2018/08/28 HTML / CSS
Harrods美国:英国最大的百货公司
2018/11/04 全球购物
学生励志演讲稿
2014/01/06 职场文书
中专生毕业个人鉴定
2014/02/26 职场文书
文明班级建设方案
2014/05/15 职场文书
canvas绘制折线路径动画实现
2021/05/12 Javascript
Python机器学习之决策树和随机森林
2021/07/15 Javascript
Mysql使用全文索引(FullText index)的实例代码
2022/04/03 MySQL
微软官方消息,在 2023 年 4 月 11 日之后微软将不再为 Office 2013 和 Skype for Business 2015 提供安全更新
2022/04/21 数码科技