JavaScript 表单脚本——“富文本编辑”的注意要点 - JavaScript学习笔记
富文本测试
BX9054: 各浏览器对 document.execCommand 方法的首参数可选值范围存在差异
部分内容来自w3c help:http://w3help.org/zh-cn/kb/
w3cHelp
在页面中嵌入一个包含空的HTML页面的iframe。通过设置designMode属性,这个空白的HTML页面就可以被编辑,编辑对象就是body元素的HTML代码。designMode属性有两个可能的值:on和off(默认值)。
window.addEventListener("load", function () { frames["firstFrame"].document.designMode = "on"; //这里返回错误信息"Blocked a frame with origin "null" from accessing a frame with origin "null". Protocols, domains, and ports must match."是因为环境的问题,protocols为file,放在浏览器上就没有问题了。});
使用contenteditable
属性
只要把元素设置contenteditable属性就行了(它的属性值有3个,true表示打开,false表示关闭,inhert表示从父元素那里继承。):
hello
任何元素都可以,甚至是button,不过设置之后你会觉得很怪异。
操作富文本ocument.execCommand()
方法
与富文本编辑交互的方式,就是使用document.execCommand()
。这个方法可以对文档执行预定义的命令,而且可以应用大多数格式。
可以为document.execCommand()
方法传递3个参数:要执行的命令名称,表示浏览器是否应该为当前命令提供用户界面的一个布尔值和执行命令必须的一个值(不需要值,可设为null)。为了保证浏览器兼容,需要设置第二个参数为false。
另外在各浏览器对应的开发者站点 msdn.microsoft.com (MSDN)、developer.mozilla.org (Mozilla Developer Network)、developer.apple.com (Apple Developer)、dev.opera.com (Opera Developer Community) 中,MSDN 与 Mozilla Developer Network 均有详细的 execCommand 方法的首参数可选值描述,Opera Developer Community 有简要说明, Apple Developer 无任何可查资料。
不同浏览器支持的预定义命令不一样,下标是被支持最多的命令(加粗的):
2D-Position 允许通过拖曳移动绝对定位的对象。
AbsolutePosition 设定元素的 position 属性为“absolute”(绝对)。
BackColor 设置或获取当前选中区的背景颜色。
BlockDirLTR 目前尚未支持。
BlockDirRTL 目前尚未支持。
Bold 切换当前选中区的粗体显示与否。
BrowseMode 目前尚未支持。
Copy 将当前选中区复制到剪贴板。
CreateBookmark 创建一个书签锚或获取当前选中区或插入点的书签锚的名称。
CreateLink 在当前选中区上插入超级链接,或显示一个对话框允许用户指定要为当前选中区插入的超级链接的 URL。
Cut 将当前选中区复制到剪贴板并删除之。
Delete 删除当前选中区。
DirLTR 目前尚未支持。
DirRTL 目前尚未支持。
EditMode 目前尚未支持。
FontName 设置或获取当前选中区的字体。
FontSize 设置或获取当前选中区的字体大小。
ForeColor 设置或获取当前选中区的前景(文本)颜色。
FormatBlock 设置当前块格式化标签。
Indent 增加选中文本的缩进。
InlineDirLTR 目前尚未支持。
InlineDirRTL 目前尚未支持。
InsertButton 用按钮控件覆盖当前选中区。
InsertFieldset 用方框覆盖当前选中区。
InsertHorizontalRule 用水平线覆盖当前选中区。
InsertIFrame 用内嵌框架覆盖当前选中区。
InsertImage 用图像覆盖当前选中区。
InsertInputButton 用按钮控件覆盖当前选中区。
InsertInputCheckbox 用复选框控件覆盖当前选中区。
InsertInputFileUpload 用文件上载控件覆盖当前选中区。
InsertInputHidden 插入隐藏控件覆盖当前选中区。
InsertInputImage 用图像控件覆盖当前选中区。
InsertInputPassword 用密码控件覆盖当前选中区。
InsertInputRadio 用单选钮控件覆盖当前选中区。
InsertInputReset 用重置控件覆盖当前选中区。
InsertInputSubmit 用提交控件覆盖当前选中区。
InsertInputText 用文本控件覆盖当前选中区。
InsertMarquee 用空字幕覆盖当前选中区。
InsertOrderedList 切换当前选中区是编号列表还是常规格式化块。
InsertParagraph 用换行覆盖当前选中区。
InsertSelectDropdown 用下拉框控件覆盖当前选中区。
InsertSelectListbox 用列表框控件覆盖当前选中区。
InsertTextArea 用多行文本输入控件覆盖当前选中区。
InsertUnorderedList 切换当前选中区是项目符号列表还是常规格式化块。
Italic 切换当前选中区斜体显示与否。
JustifyCenter 将当前选中区在所在格式化块置中。
JustifyFull 目前尚未支持。
JustifyLeft 将当前选中区所在格式化块左对齐。
JustifyNone 目前尚未支持。
JustifyRight 将当前选中区所在格式化块右对齐。
LiveResize 迫使 MSHTML 编辑器在缩放或移动过程中持续更新元素外观,而不是只在移动或缩放完成后更新。
MultipleSelection 允许当用户按住 Shift 或 Ctrl 键时一次选中多于一个站点可选元素。
Open 目前尚未支持。
Outdent 减少选中区所在格式化块的缩进。
OverWrite 切换文本状态的插入和覆盖。
Paste 用剪贴板内容覆盖当前选中区。
PlayImage 目前尚未支持。
Print 打开打印对话框以便用户可以打印当前页。
Redo 目前尚未支持。
Refresh 刷新当前文档。
RemoveFormat 从当前选中区中删除格式化标签。
RemoveParaFormat 目前尚未支持。
SaveAs 将当前 Web 页面保存为文件。
SelectAll 选中整个文档。
SizeToControl 目前尚未支持。
SizeToControlHeight 目前尚未支持。
SizeToControlWidth 目前尚未支持。
Stop 目前尚未支持。
StopImage 目前尚未支持。
StrikeThrough 目前尚未支持。
Subscript 目前尚未支持。
Superscript 目前尚未支持。
UnBookmark 从当前选中区中删除全部书签。
Underline 切换当前选中区的下划线显示与否。
Undo 目前尚未支持。
Unlink 从当前选中区中删除全部超级链接。
Unselect 清除当前选中区的选中状态。
可以在任何时候使用这些命令来修改富文本区域的外观:
frames["framing"].document.execCommand("bold", false, null);
同样也使用于页面中contenteditable属性为“true”的区块,只要把框架的引用替换成当前窗口的document对象就可以了:
p.addEventListener("contextmenu", function () { event.preventDefault(); document.execCommand("backcolor", false, "red");});
上述代码当点击右键会将p元素的backgroundColor颜色变为red(在chrome上,这则代码会在p元素周围加上span代码并附上style属性);
除了命令之外,还有一些与命令相关的方法。
第一个方法是queryCommandEnabled()
,可以检验是否可以针对当前选择的文本或者当前插入字符处所在的位置执行相应的命令。这个方法接收一个参数:即要检测的命令。如果允许返回true。但并不意味着可以执行命令,只是该命令对当前文本可以或不可以执行。
console.log(document.queryCommandSupported("bold"));
第二个方法是queryCommandState()
方法用来确定是否已将指定的命令应用到了选择的文本。
第三个方法是queryCommandValue()
方法用于取得执行命令时传入的值。
富文本选区
在富文本编辑器中,使用框架(iframe)的getSelection()
方法,可以确定实际选择的文本。这个方法是window对象和document对象的属性,调用它返回一个表示当前选择文本的selection
对象。
每个Selection对象都有下面的属性:
anchorNode: 选区起点所在的节点
anchorOffset: 到达选区起点位置之前跳过的anchorNode中的字符数量
focusNode: 选区终点所在的节点
focusOffset: focusNode中包含在选区之内的字符数量
isCollapsed: 起点终点是否重合
rangeCount: 包含DOM范围的数量
type:
baseNode:
baseOffset:
extentNode:
extentOffset:
以及方法:
getRangeAt(index): 返回索引对应的选区中的DOM范围
addRange(range): 将指定的DOM范围添加到选区中
removeAllRanges: 移除所有DOM范围
removeRange(range): 从选区中移除指定的DOM范围
collapse(node, offset): 将选区折叠到指定节点中的相应的文本偏移位置
collapseToStart: 折叠到起点
collapseToEnd: 折叠到终点
extend(node,offset): 通过将focusNode和focusOffset移动到指定的值来扩展选区
selectAllChildren(node): 清除选区并选择指定节点的所有子节点
deleteFromDocument: 从文档中删除选区中的文本与document.execCommand("delete",false,null)相同
containsNode(node): 确定指定的节点是否包含在选区中
toString(): 返回选区所包含的文本内容
empty:
setPosition:
setBaseAndExtent:
modify:
toString:
constructor:
如,获取选择的文本:
var selection = document.getSelection();console.log(selection.toString());
又如当用户选择文本后右键改变目标style:
p.addEventListener("contextmenu", function() { event.preventDefault(); document.execCommand('copy',''); //selection富文本选区 var selection = document.getSelection(); //获取选择的文本 var selectedText = selection.toString(); // 取得代表选区的范围 var range = selection.getRangeAt(0); //新建一个span设置style的背景颜色为黄色 var span = document.createElement("span"); span.style.backgroundColor = "yellow"; range.surroundContents(span);});
部分旧版浏览器需要使用window.getSelection()或document.getSelection();
IE则需要使用它浏览器本身的text属性等。也可以使用htmlText属性和pasteHTML()方法等。