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

来源:互联网 发布:方正兰亭黑简体mac版 编辑:程序博客网 时间:2024/06/05 17:43

      怎么说呢,刚包完夜吧,应该很累了,但现在仍有力气敲打着这些字符,看来我还没有到此为止啊。

       废话少说,最近写了个在线的编辑器,类似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兼容的框架。

        恩,好好加油吧。