谈谈HTML网页编辑器技术实现技术
前段时间终于把网站的编辑器做的还算有个样子了,至少符合我对编辑器的要求(使用简单,不能产生垃圾节点,能够和网站完美的融合,源码结构符合要求)。最近实在忙,忙的一直没有时间认真的去学点东西,拖到现在才写这篇文章,很多东西又忘记的差不多了。
网站编辑器是非常重要的,重要到直接关系网站的成败。
但目前没有哪一家公司重视过这样一个东西,随随便便找个开源的编辑器就用上了,以致于国内出不了牛逼的新闻媒体公司。大家去看看新浪博客,看看微信网页版经常出现的 ,就一定明白,国内的产品都做的很烂很烂的,当然微信出现空白实体是因为各部门协调不一致造成的,跟编辑器没有关系。
再啰嗦一点,其实 HTML 和 DOM 本身是不太适合做编辑器的,要兼容老的浏览器就非常的困难,于是产生了很多的黑技术。在我看来,兼容老的 IE 系列是没有意义了,但兼容现代浏览器还是很容易的事情。
先谈一谈 Selection
获取 selection 对象非常简单,如下所示:
getSelection(); // or window.getSelection();
selection 对象有一些属性,对于现代浏览器有四个比较重要的属性,分别是 anchorNode,focusNode,baseNode,extentNode。在一些比较老的浏览器中,也可能出现没有 baseNode 和 extentNode 的。特别注意的是,在 stackoverlow 上竟然有人说 baseNode 是 anchorNode 别名,extentNode 是 focusNode 的别名,其实这种说法是不对的,至少 extentNode 和 focusNode 在很多情况下就不同,这也是我在后面写编辑器时发现的。
- Selection.anchorNode 选择区域的开始节点
- Selection.focusNode 选择区域的结束节点
- rangeCount 选择的区域数量,一般浏览器都是一个,唯独 firefox 可以多个
- isCollapsed 表示当前选区是否倒塌,倒塌表示是光标状态,其他都是选中状态
Dom 的一些属性需要大量的练习和观察,通过文字很难描述清楚。
Range 对象
range 对象在 modern 浏览器中不能通过 window 对象创建,需要使用 document 对象创建,如下示例:
document.createRange();
range 对象有很多可以设置起始和结束位置的方法,比如 setStart,setEnd,setStartAfter,setStartBefore,setEndBefore,setEndAfter 等。设置好 range 对象后,调用 selection 的 addRange 方法即可实现选区。
selection.removeAllRanges(); selection.addRange(range);
document.execCommand 方法
了解 range 和 selection 对编辑器的操作是有好处的,但是最后发现,在选中后操纵选区中的 DOM 节点变得特别麻烦,比如加粗,加链接等。所以,在编辑选中的内容,还是 execCommand 比较方便,这个方法运行的结果和浏览器的差异比较大,如下所示:
document.execCommand('bold'); document.execCommand('insertHTML',1,'<strong>'+getSelection()+'</strong>'); document.execCommand('insertHTML',1,'<a href="lmlphp.com">lmlphp</a>');
最后发现,也就 insertHTML 方法比较实用了。