自己写的兼容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 相关文章推荐
通过jquery实现tab标签浏览效果
Feb 20 Javascript
Javascript中的Split使用方法与技巧
Mar 09 Javascript
JavaScript之HTMLCollection接口代码
Apr 27 Javascript
jquery1.9 下检测浏览器类型和版本的方法
Dec 26 Javascript
JS字符串拼接在ie中都报错的解决方法
Mar 27 Javascript
使用Plupload实现直接上传附件至七牛云存储
Dec 26 Javascript
js实现网页多级级联菜单代码
Aug 20 Javascript
JS+HTML5实现图片在线预览功能
Jul 22 Javascript
JQuery用$.ajax或$.getJSON跨域获取JSON数据的实现代码
Sep 23 jQuery
微信小程序的日期选择器的实例详解
Sep 29 Javascript
JavaScript实现简单的计算器
Jan 16 Javascript
JavaScript的一些小技巧分享
Jan 06 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 常用算法和时间复杂度
2013/07/01 PHP
学习PHP的数组总结【经验】
2016/05/05 PHP
php 删除指定文件夹的实例讲解
2017/07/25 PHP
Thinkphp3.2简单解决多文件上传只上传一张的问题
2017/09/26 PHP
php+laravel依赖注入知识点总结
2019/11/04 PHP
点图片上一页下一页翻页效果
2008/07/09 Javascript
jquery 图片预加载 自动等比例缩放插件
2008/12/25 Javascript
NodeJS的url截取模块url-extract的使用实例
2013/11/18 NodeJs
JavaScript制作简易的微信打飞机
2015/03/31 Javascript
JavaScript知识点总结(十六)之Javascript闭包(Closure)代码详解
2016/05/31 Javascript
浅谈jQuery双事件多重加载的问题
2016/10/05 Javascript
Bootstrap 轮播(Carousel)插件
2016/12/26 Javascript
JavaScript中Promise的使用详解
2017/02/26 Javascript
JavaScript实现各种排序的代码详解
2017/08/28 Javascript
用vue封装插件并发布到npm的方法步骤
2017/10/18 Javascript
vue脚手架中配置Sass的方法
2018/01/04 Javascript
集成vue到jquery/bootstrap项目的方法
2018/02/10 jQuery
微信小程序自定义键盘 内部虚拟支付
2018/12/20 Javascript
Openlayers学习之地图比例尺控件
2020/09/28 Javascript
Vue实现简单计算器
2021/01/20 Vue.js
[01:59]DOTA2首部纪录片《Free to play》预告片
2014/03/12 DOTA
python使用xauth方式登录饭否网然后发消息
2014/04/11 Python
python如何通过实例方法名字调用方法
2018/03/21 Python
python pillow模块使用方法详解
2019/08/30 Python
Python lambda表达式filter、map、reduce函数用法解析
2019/09/11 Python
综合素质的自我鉴定
2013/10/07 职场文书
初中地理教学反思
2014/01/11 职场文书
培训专员岗位职责
2014/02/26 职场文书
平面设计师岗位职责
2014/09/18 职场文书
抄袭同学作业检讨书1000字
2014/11/20 职场文书
公务员政审材料
2014/12/23 职场文书
志愿者事迹材料
2014/12/26 职场文书
2015年乡镇党务公开工作总结
2015/05/19 职场文书
springboot使用Redis作缓存使用入门教程
2021/07/25 Redis
python读取并查看npz/npy文件数据以及数据显示方法
2022/04/14 Python
LeetCode189轮转数组python示例
2022/08/05 Python