自己写的兼容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 面试题随笔
Mar 31 Javascript
js中页面的重新加载(当前页面/上级页面)及frame或iframe元素引用介绍
Jan 24 Javascript
JavaScript中的普通函数与构造函数比较
Apr 07 Javascript
jQuery时间日期三级联动(推荐)
Nov 27 Javascript
JS生成和下载二维码的代码
Dec 07 Javascript
jQuery动态生成表格及右键菜单功能示例
Jan 13 Javascript
解析Vue2.0双向绑定实现原理
Feb 23 Javascript
angular bootstrap timepicker TypeError提示怎么办
Jun 13 Javascript
Vue.js 实现数据展示全部和收起功能
Sep 05 Javascript
vue+elementUI动态生成面包屑导航教程
Nov 04 Javascript
Vue路由管理器Vue-router的使用方法详解
Feb 05 Javascript
Vue和React有哪些区别
Sep 12 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设计模式 Adapter(适配器模式)
2011/06/26 PHP
简单谈谈PHP面向对象之标识对象
2017/06/27 PHP
PHP基于PDO调用sqlserver存储过程通用方法【基于Yii框架】
2017/10/07 PHP
在云虚拟主机部署thinkphp5项目的步骤详解
2017/12/21 PHP
php删除一个路径下的所有文件夹和文件的方法
2018/02/07 PHP
Laravel使用scout集成elasticsearch做全文搜索的实现方法
2018/11/30 PHP
java解析json方法总结
2019/05/16 PHP
一个判断email合法性的函数[非正则]
2008/12/09 Javascript
解析URI与URL之间的区别与联系
2013/11/22 Javascript
jquery新的绑定事件机制on方法的使用方法
2014/04/15 Javascript
BOM之navigator对象和用户代理检测
2017/02/10 Javascript
完美实现js选项卡切换效果(二)
2017/03/08 Javascript
XMLHttpRequest对象_Ajax异步请求重点(推荐)
2017/09/28 Javascript
JS实现百度搜索接口及链接功能实例代码
2018/02/02 Javascript
jQuery的Ajax接收java返回数据方法
2018/08/11 jQuery
vue项目中使用Svg的方法
2018/10/24 Javascript
微信小程序中weui用法解析
2019/10/21 Javascript
vue弹出框组件封装实例代码
2019/10/31 Javascript
Vue+Bootstrap收藏(点赞)功能逻辑与具体实现
2020/10/22 Javascript
nuxt.js添加环境变量,区分项目打包环境操作
2020/11/06 Javascript
[01:56]生活中的妖精之七夕特别档
2016/08/09 DOTA
python 接口返回的json字符串实例
2018/03/27 Python
Python 查找list中的某个元素的所有的下标方法
2018/06/27 Python
如何使用Python实现自动化水军评论
2019/06/26 Python
python 实现的发送邮件模板【普通邮件、带附件、带图片邮件】
2019/07/06 Python
德国baby-markt婴儿用品瑞士网站:baby-markt.ch
2017/06/09 全球购物
英国大码女性时装零售商:Evans
2018/08/29 全球购物
Solid & Striped官网:美国泳装品牌
2019/06/19 全球购物
库存图片、照片、矢量图、视频和音乐:Shutterstock
2021/02/12 全球购物
屈臣氏菲律宾官网:Watsons菲律宾
2020/06/30 全球购物
Lucene推荐的分页方式是什么?
2015/12/07 面试题
关于梦想的演讲稿
2014/05/05 职场文书
法学院毕业生求职信
2014/06/25 职场文书
公司趣味运动会开幕词
2016/03/04 职场文书
2016创先争优活动党员公开承诺书
2016/03/24 职场文书
Html分层的box-shadow效果的示例代码
2021/03/30 HTML / CSS