教你做个在线html编辑器
最近用js代码编写了一个在线html编辑器(或称在线富文本编辑器),用它用户可在线编写丰富网页内容,如字体、字体颜色、插入表格、链接、图片、多媒体。好东西写出来与编辑爱好者分享。
首先,在网页上插入一个iframe标签,一些按钮用或图片标签等用于执行相关命令。为iframe标签设置id、name等属性,这里我们设iframe标签的id
与name值为ifrm1然后新建一个js文件并在刚刚的网页中引用它。
下面,开始编写js代码。
首先,要编写一个函数对ifrm1初始化,使iframe可以编辑,函数中代码如下。
ifrm1.document.designMode = "On"
ifrm1.document.body.contentEditable = "True";
下面我们来实现一些主要功能,在实现功能前记得要使ifrm1得到焦点,即:ifrm1.focus()
现在,我们来设置字体,如字体名称、颜色、加粗、倾斜、下划线、删除线等。我们可以用document.execCommand进行操作。
字体名称:ifrm1.document.execCommand("FontName", true, 字体名称)如宋体、字体等。
字体颜色:ifrm1.document.execCommand("forecolor", "", 颜色值);一般用16进制来表示,当然也可用一些特定颜色单词来表示,如red、green、blue等。
粗体:ifrm1.document.execCommand("Bold", true, null);
倾斜:ifrm1.document.execCommand("Italic", true, null);
下划线:ifrm1.document.execCommand("Underline", true, null);
删除线:ifrm1.editorid.document.execCommand("Strikethrough", true, null);
剪贴、复制、粘贴、撤消、重做,分别对应:
ifrm1.document.execCommand("cut");o
ifrm1.document.execCommand("copy");
ifrm1.document.execCommand("paste");
ifrm1.document.execCommand("undo");
ifrm1.document.execCommand("redo");
插入表格,在表格前我们需要采集一些数据,比如表宽、几行几列、单元格间距等,我们现对用div来模拟一个对话框,用于采集刚刚说到一些数据(为什么要使用模拟对话框,如何模拟
对话框会在下一篇文章中单独介绍)。我们来定义一些需要的变量名行数、列数、表宽、边宽、单元格间距、表背景色、边框色、对齐方式这里我们分别定义为row、col、tabwidth、
borderwidth、cellpad、tabcolor、bordercolor、tablealgin。
然后,来写html代码,如下:
var tablestring = "<table border='" + borderwidth + "' cellspacing='0' width='" + tabwidth + "' cellpadding='" + cellpad + "' align='" + tablealgin + "' bgcolor='" +
tabcolor + "' bordercolor='" + bordercolor + "' style='border-collapse:collapse'>";
for (i = 1; i <= row; i++) {
tablestring = tablestring + "<tr>";
for (j = 1; j <= col; j++) {
tablestring = tablestring + "<td> </td>";
}
tablestring = tablestring + "</tr>";
}
tablestring = tablestring + "</table>";
写到这儿,有些重点的地方必须提一个,简单地说是兼容性问题,首先来说ie8及之前的浏览器可以使用ifrm1.document.selection.createRange().pasteHTML(tablestring );但在谷歌
等其它浏览器中不支持ifrm1.document.selection,而是ifrm1.document.getSelection。所以,我们可以使用ifrm1.document.execCommand('InsertHtml', false, tablestring),而ie浏览
器不支持document.execCommand('InsertHtml')命令,根据这两点我们可以写个判断函数,来根据浏览器不同而执行相应命令。这个函数这样写:
function inserthtmlcode(iframeid, htmlcode)
{
iframeid.focus();
//var code1 = "<a href=''>ddddd</a>"
var _doc = editorid.document;
if (_doc.selection) //ie 9 之前
{
_doc.selection.createRange().pasteHTML(htmlcode);
}
else //ie9及以后、谷歌等浏览器
{
_doc.execCommand('InsertHtml', false, htmlcode);
}
}
这样一来上面的插入表格我们就可以写成inserthtmlcode(ifrm1,tablestring)。
然而事情并没这样简单结束了,刚才说了在ie8及以前版本只支持document.selection,ie9中既支持document.selection,也支持document.getSelection,但是到ie11和谷哥一样只支持
document.getSelection,并且ie11仍然不支持document.execCommand('InsertHtml')。
是不是很绕,有些晕,至少我是。ie真是个坑。不过这并不是没有解决办法了:
我们写来两个函数判断浏览器版本。第一个判断是否是ie浏览器,第二个是否支持document.selection或document.selection
function isIE() { //ie? //是否是ie浏览器
if (!!window.ActiveXObject || "ActiveXObject" in window)
return true;
else
return false;
}
function compatibilityvalue(iframeid)
{
var r=0;
if (isIE() && iframeid.document.selection) //ie11以下浏览器支持document.selection.createRange().pasteHTML
{
r = 1;
}
else if (isIE() == false && !(iframeid.document.selection)) //谷歌等浏览器不支持document.selection.createRange().pasteHTML,但支持execCommand('InsertHtml')
{
r = 2;
}
else //ie11及以上浏览器既不支持document.selection.createRange().pasteHTML,也不支持execCommand('InsertHtml')
{
r = 3;
}
return r;
}
然后通过增加html节点的方式来实现ie11插入表格:
if (compatibilityvalue(ifrm1) == 3)
{
ifrm1.focus();
var xtable = ifrm1.document.createElement("table");
xtable.border = borderwidth;
xtable.cellSpacing = 0;
xtable.cellPadding = cellpad;
xtable.align = tablealgin;
xtable.bgColor = tabcolor;
xtable.borderColor = bordercolor;
xtable.width = tabwidth;
var selection = ifrm1.document.getSelection();
var range = ifrm1.document.getSelection().getRangeAt(0);
range.deleteContents();
for (i = 1; i <= row; i++)
{
var xtr = ifrm1.document.createElement("tr");
for (j = 1; j <= col; j++)
{
xtd = ifrm1.document.createElement("td");
xtd.innerHTML = " "
xtr.appendChild(xtd);
}
xtable.appendChild(xtr);
}
range.insertNode(xtable);
}
else
{
var tablestring = "<table border='" + borderwidth + "' cellspacing='0' width='" + tabwidth + "' cellpadding='" + cellpad + "' align='" + tablealgin + "'
bgcolor='" + tabcolor + "' bordercolor='" + bordercolor + "' style='border-collapse:collapse'>";
for (i = 1; i <= row; i++) {
tablestring = tablestring + "<tr>";
for (j = 1; j <= col; j++) {
tablestring = tablestring + "<td> </td>";
}
tablestring = tablestring + "</tr>";
}
tablestring = tablestring + "</table>";
var content = ifrm1.document.body.innerHTML;
inserthtmlcode(ifrm1, tablestring);
}
同样的,我们可以借鉴上述方法来创建图片、链接等。
说微软ie是坑货,还有一个就是,失去选择范围的问题。比如设置字体颜色,我们可能需要div来模拟一个对话框,采集颜色,你会发现颜色采集后,在ie中你选中的文字并没有变成相应
颜色,但在谷歌、火狐中却可以,仔细观察发现,谷歌、火狐在你采集颜色时,刚刚所选的文字仍是选中的,但在ie中,文字却取消选中。所以在ie中我们需要先获得选中的内容,在取完值
后在还原选中内容。还是写两个函数
function getrange(iframeid) {
if (iframeid.document.selection) {
var range = iframeid.document.selection.createRange();
SelectionBookmark = range.getBookmark();
}
else
{
var range = iframeid.document.getSelection();
SelectionBookmark = range.getRangeAt(0);
}
}
function setrange(iframeid) {
if (SelectionBookmark)
{
if (iframeid.document.selection)
{
var range = iframeid.document.body.createTextRange();
range.moveToBookmark(SelectionBookmark);
range.select();
SelectionBookmark = null;
}
else
{
var range = iframeid.document.createRange();
range.selectNode(iframeid.document.body);
iframeid.document.getSelection().addRange(SelectionBookmark);
SelectionBookmark = null;
}
然后在“弹出模拟对话框”我们先getrange,在采集完数据后我们再setrange。
这样,我们已实现了编辑器的基本功能。综上述,划下重点:
1.document.execCommand实现强大,可以实现很多功能,有兴趣可网上搜索document.execCommand的参数及功能。但少部份命令不是所有浏览器支持,如execCommand('InsertHtml')。
2.iframe的选择内容的问题,即:document.selection()与document.getSelection();
3.IE11以后创建一些html元素可使用document.createElement("元素名"),然后insertNode("定义元素变量")。