最近在研究富文本编译器,也在网上看了一些资料,大致了解了一下几款富文本编译器,比如说(kissy_editor,ueditor,TinyMCE,kindeditor)。每个都是js牛人开发出来的,让我一度羡慕嫉妒恨啊,但回头想想自己去实现一个能获取更多知识。
于是我开始查阅一些资料,首先我去了解里面的功能是怎么实现的,结果我发现一个共同点就是通过js提供的execCommand函数去实现里面每个功能,这让我一下子恍然大悟,这个就是富文本编译器的核心机制,无论是哪种富文本编译器都会引用execCommand函数去实现功能。
先来看看这个execCommand函数是怎么玩的:
document.execCommand(sCommand[,交互方式, 动态参数])
注: 1.其中sCommand是一个指令参数,
2.交互参数方式如果是true将显示对话框,如果为false将不显示对话框
3.动态参数一般为一可用值或属性值
接下来是指令参数的命名和解释:
//相当于单击文件中的打开按钮
document.execCommand(”Open”);
//将当前页面另存为
document.execCommand(”SaveAs”);
//剪贴选中的文字到剪贴板;
document.execCommand(”Cut”,”false”,null);
//删除选中的文字;
document.execCommand(”Delete”,”false”,null);
//改变选中区域的字体;
document.execCommand(”FontName”,”false”,sFontName);
//改变选中区域的字体大小;
document.execCommand(”FontSize”,”false”,sSize|iSize);
//设置前景颜色;
document.execCommand(”ForeColor”,”false”,sColor);
//使绝对定位的对象可直接拖动;
document.execCommand(”2D-Position”,”false”,”true”);
//使对象定位变成绝对定位;
document.execCommand(”AbsolutePosition”,”false”,”true”);
//设置背景颜色;
document.execCommand(”BackColor”,”false”,sColor);
//使选中区域的文字加粗;
document.execCommand(”Bold”,”false”,null);
//复制选中的文字到剪贴板;
document.execCommand(”Copy”,”false”,null);
//设置指定锚点为书签;
document.execCommand(”CreateBookmark”,”false”,sAnchorName);
//将选中文本变成超连接,若第二个参数为true,会出现参数设置对话框;
document.execCommand(”CreateLink”,”false”,sLinkURL);
//设置当前块的标签名;
document.execCommand(”FormatBlock”,”false”,sTagName);
//相当于单击文件中的打开按钮
document.execCommand(”Open”);
//将当前页面另存为
document.execCommand(”SaveAs”);
//剪贴选中的文字到剪贴板;
document.execCommand(”Cut”,”false”,null);
//删除选中的文字;
document.execCommand(”Delete”,”false”,null);
//改变选中区域的字体;
document.execCommand(”FontName”,”false”,sFontName);
//改变选中区域的字体大小;
document.execCommand(”FontSize”,”false”,sSize|iSize);
//设置前景颜色;
document.execCommand(”ForeColor”,”false”,sColor);
//使绝对定位的对象可直接拖动;
document.execCommand(”2D-Position”,”false”,”true”);
//使对象定位变成绝对定位;
document.execCommand(”AbsolutePosition”,”false”,”true”);
//设置背景颜色;
document.execCommand(”BackColor”,”false”,sColor);
//使选中区域的文字加粗;
document.execCommand(”Bold”,”false”,null);
//复制选中的文字到剪贴板;
document.execCommand(”Copy”,”false”,null);
//设置指定锚点为书签;
document.execCommand(”CreateBookmark”,”false”,sAnchorName);
//将选中文本变成超连接,若第二个参数为true,会出现参数设置对话框;
document.execCommand(”CreateLink”,”false”,sLinkURL);
介绍完了execCommand函数的说明,接下来看看在kindeditor富文本编译器中是这样引用:
function _nativeCommand(doc, key, val) {
try {
doc.execCommand(key, false, val);
} catch(e) {}
}
通过_nativeCommand函数传参,然后放到doc.execCommand中进行实现功能机制。
看下淘宝的kissy_editor中
在这里有个函数引用this.editor.execCommand()
exec: function() {
this.editor.execCommand(this.name)
}
然后这个函数的定义如下
execCommand: function(m, n, l) {
this.contentWin.focus();
k.Command.exec(this.contentDoc, m, n, l)
}
其中k.Command.exec这个exec函数已经封装在下面的add定义中了,kissy_editor这个还引用了雅虎提供的一些技术进行实现
KISSY.Editor.add("core~command",
function(f) {
var d = YAHOO.env.ua,
b = {
backColor: d.gecko ? "hiliteColor": "backColor"
},
c = "bold,italic,underline,strikeThrough",
a = "styleWithCSS",
e = "execCommand";
f.Command = {
exec: function(i, h, j, g) {
h = b[h] || h;
this._preExec(i, h, g);
i[e](h, false, j)
},
_preExec: function(i, h, g) {
if (d.gecko) {
var j = typeof g === "undefined" ? (c.indexOf(h) === -1) : g;
i[e](a, false, j)
}
}
}
});
而在tinymce中看核心代码tinymce.min.js看的我是要崩溃,1万多行的js封装,里面每块都用引用execCommand,但每块都会单独定义出来,接下来
看看tinymce是怎么实现的:
(1) InsertHorizontalRule: function() {
r.execCommand("mceInsertContent", !1, "<hr />")
}
(2) e.execCommand("FontSize", !1, t.control.settings.value)
(3)function v() {
try {
i.getDoc().execCommand("enableObjectResizing", !1, !1)
} catch(e) {}
}
列举这3种,还有很多种写法,看的我是眼花缭乱。
接下来看看百度富文本编译器的引用
me.document.execCommand('2D-position', false, false);
综合上述所展示的,核心还是那个核心,就是外界的封装不同,页面风格不一样!
有的富文本编译器自带控件可配置方式,需要哪些功能的展示,自己随意加上配置,举例,最近刚研究的TinyMCE4.0.28版本,
它的配置可以这样设计 在页面先引入 <script type="text/javascript" src="js/tinymce/tinymce.min.js"></script>,然后再加上
<script type="text/javascript">
tinymce.init({
selector: "textarea",
theme: "modern",
plugins: [
"advlist link image lists charmap print preview hr anchor pagebreak spellchecker",
],
toolbar: "insertfile undo redo | styleselect | bold italic | alignleft aligncenter alignright",
style_formats: [
{title: 'Bold text', inline: 'b'},
{title: 'Red text', inline: 'span', styles: {color: '#ff0000'}
],
language:'zh_CN'
});
</script>
tinymce.init函数里面添加object类型参数,插件(plugins)可以任意设置,工具条(toolbar)内容可以任意设置所展现在页面中的功能块。一旦找到实现的一些规律的话,自己做起来的实现思路就清晰多了。
而我自己写了一个小型的富文本编译器,花了1个多月时间,让我挑战了一次,
界面看起来很简单,功能也简单。这次我的搭建了一个js架构,跟那些大牛人比,我还是小奶牛一个,通过自己的方式去搭建一个前端结构,如图在这里我写的 execCommand操作如下
doEditCommand:function(name, arg){
try {
this.ifr.contentWindow.focus();
this.doc.execCommand(name, false, arg);
} catch(e) {}
}
原理一样,但里面功能机制还不入kissy_editor,ueditor,TinyMCE和kindeditor那么丰富,但是我学到了一些宝贵的思想和知识,富文本编译器这样的前端组件,也可以当成一个小型前端框架去理解,去学习。其他一些现实方式就不多说了,继续走在js研究的道路,“革命尚未成功,还需努力!”。