如何开发HTML编辑器

 我来答
明槐宸739
2016-04-11 · TA获得超过1045个赞
知道大有可为答主
回答量:1507
采纳率:92%
帮助的人:470万
展开全部
 开发方法如下:

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

  [javascript] view plaincopy
  var editor = document.getElementById("IFRAME的ID");
  
  var editorDoc = editor.contentWindow.document;
  var editorWindow = editor.contentWindow;
  
  editorDoc.designMode = "on";
  
  editorDoc.open();
  editorDoc.write("<html><head></head><body style='margin:0px; padding: 0px;'></body></html>");
  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
  var range = document.selection.createRange()
  在Firefox,Chrome中则使用
  [javascript] view plaincopy
  var range = window.getSelection().getRangeAt(0);
  2.2 替换选中的HTML

  通过2.1的方法获取了表示选中内容的对象后,就可以调用其方法来替换掉选中的内容。在不同的浏览器中替换选中的HTML的方法有所差异,在IE中可以只需调用range.pasteHTML就行了,在Firefox,Chrome中则使用range.deleteContents 和 range.insertNode 两个方法来实现

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

  由于2.1中获取的range对象的方法在不同浏览器中差异很大,因此,为了方便实现2.1和2.2提到的两个操作,封装了一个操作选中HTML的类SelectionRange,该类有两个方法,GetSelectedHtml和Replace,分别用于获取HTML和替换HTML。其代码如下:

  [javascript] view plaincopy
  //用于记录浏览器的类型
  var browser = {};
  
  var ua = navigator.userAgent.toLowerCase();
  
  browser.msie = (/msie ([\d.]+)/).test(ua);
  browser.firefox = (/firefox\/([\d.]+)/).test(ua);
  browser.chrome = (/chrome\/([\d.]+)/).test(ua);
  
  //获取多个节点的HTML
  function GetInnerHTML(nodes)
  {
  var builder = [];
  for (var i = 0; i < nodes.length; i++)
  {
  if (nodes[i].nodeValue != undefined)
  {
  builder.push(nodes[i].innerHTML);
  }
  else
  {
  if (nodes[i].textContent) builder.push(nodes[i].textContent.replace(/\</ig, function() { return "<"; }));
  else if (nodes[i].nodeValue) builder.push(nodes[i].nodeValue.replace(/\</ig, function() { return "<"; }));
  }
  }
  return builder.join("");
  }
  
  function SelectionRange(doc, range)
  {
  //获取选中的内容的HTML
  this.GetSelectedHtml = function()
  {
  if (range == null) return "";
  
  if (browser.msie)
  {
  if (range.htmlText != undefined) return range.htmlText;
  else return "";
  }
  else if (browser.firefox || browser.chrome)
  {
  return GetInnerHTML(range.cloneContents().childNodes);
  }
  else
  {
  return "";
  }
  }
  
  //用html替换选中的内容的HTML
  this.Replace = function(html)
  {
  if (range != null)
  {
  if (browser.msie)
  {
  if (range.pasteHTML != undefined)
  {
  //当前选中html可能以为某种原因(例如点击了另一个DIV)而丢失,重新选中
  range.select();
  range.pasteHTML(html);
  return true;
  }
  }
  else if (browser.firefox || browser.chrome)
  {
  if (range.deleteContents != undefined && range.insertNode != undefined)
  {
  //将文本html转换成DOM对象
  var temp = doc.createElement("DIV");
  temp.innerHTML = html;
  
  var elems = [];
  for (var i = 0; i < temp.childNodes.length; i++)
  {
  elems.push(temp.childNodes[i]);
  }
  
  //删除选中的节点
  range.deleteContents();
  
  //将html对应的节点(即temp的所有子节点)逐个插入到range中,并从temp中删除
  for (var i in elems)
  {
  temp.removeChild(elems[i]);
  range.insertNode(elems[i]);
  }
  return true;
  }
  }
  }
  return false;
  }
  }
  与此同时,还实现了一个函数GetSelectionRange用于获取当前选中文本对应的SelectionRange对象,

  [javascript] view plaincopy
  function GetSelectionRange(win)
  {
  var range = null;
  
  if (browser.msie)
  {
  range = win.document.selection.createRange();
  if (range.parentElement().document != win.document)
  {
  range = null;
  }
  }
  else if (browser.firefox || browser.chrome)
  {
  var sel = win.getSelection();
  if (sel.rangeCount > 0) range = sel.getRangeAt(0); else range = null;
  }
  
  return new SelectionRange(win.document, range);
  }
  2.4 修改选中的HTML的样式

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

  [javascript] view plaincopy
  function SetNodeStyle(doc, node, name, value)
  {
  if (node.innerHTML == undefined)
  {
  return node;
  }
  else
  {
  node.style[name] = value;
  
  for (var i = 0; i < node.childNodes.length; i++)
  {
  var cn = node.childNodes[i];
  if (node.innerHTML != undefined)
  {
  SetNodeStyle(doc, cn, name, value);
  }
  }
  
  return node;
  }
  }
  
  function SetStyle(doc, html, name, value)
  {
  var dom = doc.createElement("DIV");
  dom.innerHTML = html;
  
  for (var i = 0; i < dom.childNodes.length; i++)
  {
  var node = dom.childNodes[i];
  
  if (node.innerHTML == undefined)
  {
  //如果是文本节点,则转换转换成span
  var span = doc.createElement("SPAN");
  span.style[name] = value;
  if (node.nodeValue != undefined) span.innerHTML = node.nodeValue.replace(/\</ig, function() { return "<"; });
  else if (node.textContent != undefined) span.innetHTML = node.textContent.replace(/\</ig, function() { return "<"; });
  //替换掉文本节点
  dom.replaceChild(span, node);
  }
  else
  {
  SetNodeStyle(doc, node, name, value);
  }
  }
  
  return dom.innerHTML;
  }
  2.5 示例

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

  [javascript] view plaincopy
  var range = GetSelectionRange(editorWindow);
  var html = SetStyle(editorDoc, range.GetSelectedHtml(), "fontSize", "32px");
  range.Replace(html);
  同理,你可以实现设置行距,缩进,插入图片等功能。
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式