自己写的兼容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解决iframe高度自适应代码
Dec 20 Javascript
用AJAX返回HTML片段中的JavaScript脚本
Jan 04 Javascript
javascript 系统文件夹文件操作及参数介绍
Jan 08 Javascript
JavaScript 语言基础知识点总结(思维导图)
Nov 10 Javascript
Javascript基础教程之关键字和保留字汇总
Jan 18 Javascript
浅谈Sizzle的“编译原理”
Apr 14 Javascript
使用struts2+Ajax+jquery验证用户名是否已被注册
Mar 22 Javascript
javascript执行环境及作用域详解
May 05 Javascript
过期软件破解办法实例详解
Jan 04 Javascript
layui实现动态和静态分页
Apr 28 Javascript
使用VScode 插件debugger for chrome 调试react源码的方法
Sep 13 Javascript
Vue3项目打包后部署到服务器 请求不到后台接口解决方法
Feb 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 session会话的安全性分析
2011/09/08 PHP
Linux下CoreSeek及PHP扩展模块的安装
2012/09/23 PHP
php 判断字符串中是否包含html标签
2014/02/17 PHP
PHP简单获取随机数的常用方法小结
2017/06/07 PHP
thinkPHP框架动态配置用法实例分析
2018/06/14 PHP
ExtJs事件机制基本代码模型和流程解析
2010/10/24 Javascript
jquery实现商品拖动选择效果代码(自写)
2013/05/28 Javascript
javascript中自定义对象的属性方法分享
2013/07/12 Javascript
2014 HTML5/CSS3热门动画特效TOP10
2014/12/07 Javascript
jQuery 3.0中存在问题及解决办法
2016/07/15 Javascript
JS实现禁止高频率连续点击的方法【基于ES6语法】
2017/04/25 Javascript
详谈innerHTML innerText的使用和区别
2017/08/18 Javascript
Vue.js2.0中的变化小结
2017/10/24 Javascript
总结js中的一些兼容性易错的问题
2017/12/18 Javascript
详解vue-cli+element-ui树形表格(多级表格折腾小计)
2019/04/17 Javascript
基于p5.js 2D图像接口的扩展(交互实现)
2020/11/30 Javascript
[03:55]2016国际邀请赛中国区预选赛首日TOP10精彩集锦
2016/06/27 DOTA
python文件操作相关知识点总结整理
2016/02/22 Python
Python实现单词翻译功能
2017/06/06 Python
Python多继承原理与用法示例
2018/08/23 Python
Python模块、包(Package)概念与用法分析
2019/05/31 Python
Python寻找路径和查找文件路径的示例
2019/07/10 Python
Python安装及Pycharm安装使用教程图解
2019/09/20 Python
Python操作Jira库常用方法解析
2020/04/10 Python
Python绘图之二维图与三维图详解
2020/08/04 Python
Python二元算术运算常用方法解析
2020/09/15 Python
用python批量下载apk
2020/12/29 Python
CSS3让登陆面板3D旋转起来
2016/05/03 HTML / CSS
html5将图片转换成base64的实例代码
2016/09/21 HTML / CSS
俄罗斯香水和化妆品购物网站:Л’Этуаль
2018/05/10 全球购物
高中军训感想300字
2014/03/04 职场文书
成本会计岗位职责
2015/02/03 职场文书
餐饮服务食品安全承诺书
2015/04/29 职场文书
反腐倡廉观后感
2015/06/08 职场文书
html form表单基础入门案例讲解
2021/07/15 HTML / CSS
Golang bufio详细讲解
2022/04/21 Golang