您的位置:首页 > Web前端 > JavaScript

说说 JavaScript 表单脚本之富文本编辑功能

2017-07-11 15:39 316 查看
富文本编辑,即所见即所得(What You See Is What You Get)。这个技术的本质是在页面中嵌入一个包含空 HTML 页面的 iframe。通过 designMode 属性(设置为 on),这个页面就可以被编辑,编辑对象是这个页面的
<body>
元素的 HTML

代码。

iframe 中使用一个简单的 HTML 页面就可以作为内容:

<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>Blank Page for Rich Text Editing</title>
</head>
<body>

<script type="text/javascript">

</script>
</body>
</html>


只有在页面完全加载后才能设置 designMode 属性,所以要使用 onload 事件来设置这一属性:

<iframe name="richedit" style="height: 100px;width:100px;" src="blank.htm"></iframe>

<script type="text/javascript">

EventUtil.addHandler(window, "load", function () {
frames["richedit"].document.designMode = "on";
})
</script>


打开后会看到一个类似文本框的可编辑区域。

1 使用 contenteditable 属性

把 contenteditable 属性设置给页面中的任何一个元素后,用户就可以立即编辑这个元素咯,是不是很方便呀:

<div class="editable" id="richedit" contenteditable></div>


在某个元素上设置 contenteditable 属性,也可以打开或关闭编辑模式:

var div = document.getElementById("richedit");
richedit.contenteditable = "true";


contenteditable 属性有三个值:

说明
true打开
false关闭
inherit继承自父元素
五大浏览器都支持 contenteditable 属性。移动设备的浏览器中,iOS 5+ 的 Safari 和 Android 3+ 的 Webkit 也支持这个属性。

2 操作富文本

使用 document.execCommand() 可以与富文本编辑器进行交互。它接受 3 个参数:要执行的命令名称、是否为当前命令提供用户界面(为保证跨浏览器,通常设置为 false)以及命令参数。下面列出支持最多的命令:

命令值(第 3 个参数)说明
backcolor颜色字符串设置文档的背景色。
boldnull将选择的文本转换为粗体。
copynull将选择的文本复制到剪贴板。
createlinkURL 字符串将选择的文本转换为链接,然后指向指定的 URL。
cutnull将选择的文本剪贴到剪贴板。
deletenull删除选择的文本。
fontname字体名称将选择的文本改为指定的字体。
fontsize1 ~ 7将选择的文本改为指定的字体大小。
forecolor颜色字符串将选择的文本改为指定的颜色。
formatblock需要包围当前文本块的 HTML 标签使用指定的 HTML 标签来包裹指定的文本块。
indentnull缩进文本。
inserthorizontalrulenull在光标处插入一个
<hr>
元素。
insertimage图像的 URL在光标处插入一个图像。
insertorderedlistnull在光标处插入一个
<ol>
元素。
insertunorderedlistnull在光标处插入一个
<ul>
元素。
insertparagraphnull在光标处插入一个
<p>
元素。
italicnull将选择的文本改为斜体。
justifycenternull在光标处的文本块居中对齐。
justifyleftnull在光标处的文本块左对齐。
outdentnull减少缩进。
pastenull将剪贴板中的内容粘贴到
10b73
选择的文本。
removeformatnull移除包围当前文本块的 HTML 标签,这是撤销 formatblock 命令的操作。
selectallnull选中所有文本。
underlinenull为选中的文本添加下划线。
unlinknull移除文本链接,这是撤销 createlink 命令的操作。
注意:与剪贴板相关的命令在不同的浏览器中差别很大!Opera 没有实现任何与剪贴板相关的命令,Firefox 会在默认情况下禁止这些命令。Safari 和 Chrome 实现了 cut 和 copy,但没有实现 paste。虽然不能使用 document.execCommand() 执行这些命令,但可以通过快捷键来实现同样的功能。

可以使用这些命令来改变富文本区域的外观:

<form method="post" action="javascript:alert('Form submitted!')" id="myForm">
<div id="divSimple">
<input type="button" value="Bold">
<input type="button" value="Italic">
<input type="button" value="createLink">
<input type="button" value="h1">
<input type="button" value="enabled">
<input type="button" value="state">
<input type="button" value="commandValue">
<input type="button" value="setBackground">
<!--<input type="button" value="Underline">-->
<!--<input type="button" value="Indent">-->
<!--<input type="button" value="Outdent">-->
<!--<input type="button" value="Copy">-->
<!--<input type="button" value="Cut">-->
<!--<input type="button" value="Paste">-->
</div>
<div id="richedit" style="height: 100px;width: 300px;border: dashed"
contenteditable></div>

<button type="sumbit">sumbit</button>
<input type="hidden" id="comments">
</form>
```

```
<script type="text/javascript">

(function () {

var simple = document.getElementById("divSimple");
EventUtil.addHandler(simple, "click", function (event) {
event = EventUtil.getEvent(event);
var target = EventUtil.getTarget(event);

if (target.type = "button") {
switch (target.value) {
case "Bold"://粗体
//                        document.execCommand(target.value.toLowerCase(), false, null);
document.execCommand("bold", false, null);
break;
case "Italic"://斜体
document.execCommand("italic", false, null);
break;
case "createLink"://创建链接
document.execCommand("createlink", false, "http://www.163.com");
break;
case "h1"://格式化为 h1
document.execCommand("formatblock", false, "<h1>");
break;
case "enabled"://是否可以针对当前选择的文本执行某个命令
console.log(document.queryCommandEnabled("bold"));
break;
case "state"://是否已将指定命令应用到了选择的文本
console.log(document.queryCommandState("bold"));
break;
case "commandValue"://取得执行命令时传入的值
console.log(document.queryCommandValue("fontsize"));
break;
case "setBackground"://添加黄色背景(富文本选区操作)
var selection = document.getSelection();

//取得选择的文本
var selectedText = selection.toString();

//取得代表选区的范围
var range = selection.getRangeAt(0);

//突出显示已经选择的文本
var span = document.createElement("span");
span.style.backgroundColor = "yellow";
range.surroundContents(span);
break;

}
}
});

})();
</script>


注意:虽然所有的浏览器都支持这些命令,但它们生成的 HTML 文本并不相同!比如执行 bold 命令后,IE 和 Opera 会使用
<strong>
标签包围文本,而 Safari 和 Chrome 使用的是
<b>
标签,在 Firefox 中使用的是
<span>
标签!

queryCommandEnabled() 方法是用来检查某个命令是否适用于当前选中的文本,或者是否能在当前光标处执行该命令。它接受一个参数,即要检测的命令。返回布尔值:

var result = frames["richedit"].document.queryCommandEnabled("bold");


这个命令其实并不可靠,比如在 Firefox 中禁用剪切操作的情况下,这个命令仍会返回 false。

queryCommandState() 方法用于确定某个命令是否已经应用到所选中的文本:

var result = frames["richedit"].document.queryCommandState("bold");


那些富文本编辑器就是根据这个方法返回的值来更新粗体、斜体的按钮状态的。

queryCommandValue() 可以取得执行命令时传入的值(就是 document.execCommand() 方法的第 3 个值):

var fontSize = frames["richedit"].document.queryCommandValue("fontsize");//7


# 3 富文本选区

使用 iframe 的 getSelection() 方法可以获取实际选中的文本。它会返回当前选中文本的 Selection 对象。每个 Selection 对象都有这些属性:

属性名说明
anchorNode选区起点所在的节点。
anchorOffset到达选区起点之前所跳过的 anchorNode 的字符数量。
focusNode选区终点所在的节点。
isCollapsed选区起点与终点是否重合。
rangeCount选区中包含的 DOM 范围的数量。
这些属性其实没有多少价值,我们再看看 Selection 对象所拥有的方法:

方法名说明
addRange(range)把指定的 DOM 范围添加到选区中。
collpase(node, offset)把选区折叠到指定节点中相应偏移量位置。
collapseToEnd()把选区折叠到终点。
collapseToStart()把选区折叠到起点。
deleteFromDocument()从文档中删除选区中的文本,这与 执行 document.execCommand(“delete”, false, null) 命令的结果相同。
extend(node offset)把 focusNode 和 focusOffset 移动到指定偏移量来扩展选区。
getRangeAt(index)返回索引对应选区中的 DOM 范围。
removeAllRanges()从选区中移除所有 DOM 范围,没有了范围,选区也会被移除。
removeRange(range)从选区中移除指定的 DOM 范围。
selectAllChildren(node)清除选区,然后选择指定节点的所有节点。
toString()返回选区所包含的文本内容。
这些方法很实用,可以使用它们来管理选区:

var selection = document.getSelection();

//取得选择的文本
var selectedText = selection.toString();

//取得代表选区的范围
var range = selection.getRangeAt(0);

//突出显示已经选择的文本
var span = document.createElement("span");
span.style.backgroundColor = "yellow";
range.surroundContents(span);


上面这段代码会把被选择的文本添加上黄色的背景:



4 表单和富文本

因为富文本编辑使用的是 iframe,所以它并不属于表单。所以自然不会被自动提交给服务器,因此需要手工处理。可以添加一个隐藏字段,把它的值设置为从 iframe 中提取出的 富文本内容:

<input type="hidden" id="comments">
...
var form = document.getElementById("myForm");
EventUtil.addHandler(form, "submit", function (event) {//把富文本域的值添加到表单
event = EventUtil.getEvent(event);
var target = EventUtil.getTarget(event);

target.elements["comments"].value = document.getElementById("richedit").innerHTML;
console.log(target.elements["comments"].value);
})
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: