打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
如何开发HTML编辑器

如何开发HTML编辑器

324人阅读 评论(1) 收藏 举报

目录(?)[+]

 在线的HTML内容编辑器为用户提供文本的样式控制,例如文字的颜色、字体大小等。虽然现在网上多数的编辑器(如:FCKEditor)功能相当强大的,但是在使用中需要很多的配置,因此代码往往比较“臃肿”。本文的目的就是介绍如何开发一个HTML编辑器,以方便扩展自己想要的特殊功能。

代码下载 在线演示

1.添加一个可编辑的iframe

实现HTML编辑器的第1步就是在网页中放置一个可编辑的iframe用来输入文本,使iframe可编辑方法相当简单,只需要将iframe的designMode设置为on即可,具体步骤如下:

[javascript] view plaincopy?
  1. var editor = document.getElementById("IFRAME的ID");  
  2.   
  3. var editorDoc = editor.contentWindow.document;  
  4. var editorWindow = editor.contentWindow;  
  5.   
  6. editorDoc.designMode = "on";  
  7.   
  8. editorDoc.open();  
  9. editorDoc.write("<html><head></head><body style="margin:0px; padding: 0px;" mce_style="margin:0px; padding: 0px;"></body></html>");  
  10. editorDoc.close();  

2.设置选中文本的样式

设置选中文本样式的方法最简单的方式就是使用document.execCommand,但是execCommand功能比较局限,有时不能满足需求,例如:execCommand设置字体大小只能是1-7,不能使用像素大小,而且如果你在点击工具栏按钮到调用execCommand的过程中点击了其他的DIV,iframe的选中内容会消失,这时调用execCommand是无效的。因此本文介绍另一种方法,基本思路如下:
(1) 获取选中的HTML;
(2) 修改HTML的样式;
(3) 用修改后的HTML替换选中的HTML。

2.1 获取选中的HTML

在不同的浏览器中获取选中的HTML的方法是不同的,在IE中可以使用

[javascript] view plaincopy?
  1. document.selection.createRange()  

在Firefox,Chrome中则使用

[javascript] view plaincopy?
  1. window.getSelection().getRangeAt(0);  
 

2.2 替换选中的HTML

在不同的浏览器中替换选中的HTML的方法是不同的,在IE中可以使用range.pasteHTML;在Firefox,Chrome中则使用range.deleteContents 和 range.insertNode 来实现

2.2 封装一个操作选中HTML的类

为了方便实现2.1和2.2提到的两个操作,将封装一个操作选中HTML的类SelectionRange,该类有两个方法,GetSelectedHtml和Replace,分别用于获取HTML和替换HTML。同时还实现了一个函数GetSelectionRange用于获取当前选中文本对应的SelectionRange对象,相关代码如下:

[javascript] view plaincopy?
  1. var browser = {};  
  2.   
  3. var ua = navigator.userAgent.toLowerCase();  
  4.   
  5. browser.msie = (/msie ([/d.]+)/).test(ua);  
  6. browser.firefox = (/firefox//([/d.]+)/).test(ua);  
  7. browser.chrome = (/chrome//([/d.]+)/).test(ua);  
  8.   
  9. function GetInnerHTML(nodes)  
  10. {  
  11.     var builder = [];  
  12.     for (var i = 0; i < nodes.length; i++)  
  13.     {  
  14.         if (nodes[i].nodeValue != undefined)  
  15.         {  
  16.             builder.push(nodes[i].innerHTML);  
  17.         }  
  18.         else  
  19.         {  
  20.             if (nodes[i].textContent) builder.push(nodes[i].textContent.replace(//</ig, function() { return "<"; }));  
  21.             else if (nodes[i].nodeValue) builder.push(nodes[i].nodeValue.replace(//</ig, function() { return "<"; }));  
  22.         }  
  23.     }  
  24.     return builder.join("");  
  25. }  
  26.   
  27. function SelectionRange(doc, range)  
  28. {  
  29.     this.GetSelectedHtml = function()  
  30.     {  
  31.         if (range == nullreturn "";  
  32.   
  33.         if (browser.msie)  
  34.         {  
  35.             if (range.htmlText != undefined) return range.htmlText;  
  36.             else return "";  
  37.         }  
  38.         else if (browser.firefox || browser.chrome)  
  39.         {  
  40.             return GetInnerHTML(range.cloneContents().childNodes);  
  41.         }  
  42.         else  
  43.         {  
  44.             return "";  
  45.         }  
  46.     }  
  47.   
  48.     this.Replace = function(html)  
  49.     {  
  50.         if (range != null)  
  51.         {  
  52.             if (browser.msie)  
  53.             {  
  54.                 if (range.pasteHTML != undefined)  
  55.                 {  
  56.                     range.select();  
  57.                     range.pasteHTML(html);  
  58.                     return true;  
  59.                 }  
  60.             }  
  61.             else if (browser.firefox || browser.chrome)  
  62.             {  
  63.                 if (range.deleteContents != undefined && range.insertNode != undefined)  
  64.                 {  
  65.                     var temp = doc.createElement("DIV");  
  66.                     temp.innerHTML = html;  
  67.   
  68.                     var elems = [];  
  69.                     for (var i = 0; i < temp.childNodes.length; i++)  
  70.                     {  
  71.                         elems.push(temp.childNodes[i]);  
  72.                     }  
  73.   
  74.                     range.deleteContents();  
  75.   
  76.                     for (var i in elems)  
  77.                     {  
  78.                         temp.removeChild(elems[i]);  
  79.                         range.insertNode(elems[i]);  
  80.                     }  
  81.                     return true;  
  82.                 }  
  83.             }  
  84.         }  
  85.         return false;  
  86.     }  
  87. }  
  88.   
  89. function GetSelectionRange(win)  
  90. {  
  91.     var range = null;  
  92.   
  93.     if (browser.msie)  
  94.     {  
  95.         range = win.document.selection.createRange();  
  96.         if (range.parentElement().document != win.document)  
  97.         {  
  98.             range = null;  
  99.         }  
  100.     }  
  101.     else if (browser.firefox || browser.chrome)  
  102.     {  
  103.         var sel = win.getSelection();  
  104.         if (sel.rangeCount > 0) range = sel.getRangeAt(0); else range = null;  
  105.     }  
  106.   
  107.     return new SelectionRange(win.document, range);  
  108. }  

2.4 修改选中的HTML的样式

修改选中的HTML的样式方法并不复杂,只需要将HTML转成DOM对象,然后递归的设置每一个节点对应的样式的值即可,具体代码如下:

[javascript] view plaincopy?
  1. function SetNodeStyle(doc, node, name, value)  
  2. {  
  3.     if (node.innerHTML == undefined)  
  4.     {  
  5.         return node;  
  6.     }  
  7.     else  
  8.     {  
  9.         node.style[name] = value;  
  10.   
  11.         for (var i = 0; i < node.childNodes.length; i++)  
  12.         {  
  13.             var cn = node.childNodes[i];  
  14.             if (node.innerHTML != undefined)  
  15.             {  
  16.                 SetNodeStyle(doc, cn, name, value);  
  17.             }  
  18.         }  
  19.   
  20.         return node;  
  21.     }  
  22. }  
  23.   
  24. function SetStyle(doc, html, name, value)  
  25. {  
  26.     var dom = doc.createElement("DIV");  
  27.     dom.innerHTML = html;  
  28.   
  29.     for (var i = 0; i < dom.childNodes.length; i++)  
  30.     {  
  31.         var node = dom.childNodes[i];  
  32.   
  33.         if (node.innerHTML == undefined)  
  34.         {  
  35.             var span = doc.createElement("SPAN");  
  36.             span.style[name] = value;  
  37.             if (node.nodeValue != undefined) span.innerHTML = node.nodeValue.replace(//</ig, function() { return "<"; });  
  38.             else if (node.textContent != undefined) span.innetHTML = node.textContent.replace(//</ig, function() { return "<"; });  
  39.             dom.replaceChild(span, node);  
  40.         }  
  41.         else  
  42.         {  
  43.             SetNodeStyle(doc, node, name, value);  
  44.         }  
  45.     }  
  46.   
  47.     return dom.innerHTML;  
  48. }  

2.5 示例

使用以上的代码,就可以相当方便的实现一个HTML编辑器,例如,以下代码实现将选中文本的字体大小设置为32px:

[javascript] view plaincopy?
  1. var range = GetSelectionRange(editorWindow);  
  2. var html = SetStyle(editorDoc, range.GetSelectedHtml(), "fontSize""32px");  
  3. range.Replace(html);  

同理,你可以实现设置行距,缩进,插入图片等功能。

本文给出的代码兼容IE,Firefox和Chrome,如果有其它问题可以通过EMail或者WebIM与我联系。

作者:卢春城
E-mail:mrlucc@126.com
WebIM:http://los.luchuncheng.cn/Chat.aspx?User=luchuncheng&Nickname=%u5362%u6625%u57CE
本文为作者原创文章,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
Web-第三天 JavaScript学习【悟空教程】
Firefox實用Bookmarklet推薦分享
JS操作DOM元素属性和方法(转)
javascript之DOM技术(一) - 庄周梦蝶,孰蝶是我,我是孰蝶?一梦至今,蝶我已...
一篇文章带你了解JavaScript变量
HTML5 audio标签使用js进行播放控制实例
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服