区域可编辑contenteditable的问题总结
Posted yiyi17
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了区域可编辑contenteditable的问题总结相关的知识,希望对你有一定的参考价值。
一、如何在可编辑区域div的光标处通过点击事件来添加文本内容
下面的例子是可编辑div的区域添加文本内容和判断光标位置的方法
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> 焦点位置:<input id="i1">选中文本:<input id="i2"> <div id="d1" contenteditable="true" style="width:200px;height:100px;border:1px solid black">1234567890abcdef </div> <button id="add">添加文字</button> </body> <script type="text/javascript"> add.onclick=function () { var obj= d1; var range, node; if(!obj.hasfocus) { obj.focus(); } if (window.getSelection && window.getSelection().getRangeAt) { range = window.getSelection().getRangeAt(0); range.collapse(false); node = range.createContextualFragment(‘10000ss‘); var c = node.lastChild; range.insertNode(node); if(c){ range.setEndAfter(c); range.setStartAfter(c) } var j = window.getSelection(); j.removeAllRanges(); range = window.getSelection().getRangeAt(0); j.addRange(range); } else if (document.selection && document.selection.createRange) { document.selection.createRange().pasteHTML(text); } } document.onselectionchange = function (e) { // ie11 //判断是否支持document.selection属性 if (document.selection) { var pos = 0; var range = document.selection.createRange(); var srcele = range.parentElement(); //新建一个range,焦点在开头 var copy = document.body.createTextRange(); copy.moveToElementText(srcele); //判断copy的焦点起始部分是否在range的焦点起始部分的后面 for (pos = 0; copy.compareEndPoints("StartToStart", range) < 0; pos++) { //copy的焦点向后移动一个字符 copy.moveStart("character", 1); } document.getElementById(‘i1‘).value = pos; document.getElementById(‘i2‘).value = range.htmlText; } // chrome uc if (window.getSelection) { //获取Selection对象 var se = window.getSelection(); //获取起始位置,这个是字符的序号位置,而不是坐标 var start = se.anchorOffset; //获取结束位置 var end = se.focusOffset; //获取起始的dom元素 var startEl = se.anchorNode.parentElement; //获取结束的dom元素 var endEl = se.focusNode.parentElement; //获取起始dom元素的文本内容 var startText = startEl.innerText; var txt = ‘‘; if (startEl == endEl) { txt = startText.substring(start, end); } document.getElementById(‘i1‘).value = start; document.getElementById(‘i2‘).value = txt; } } </script> </html>
range.startOffset;相对于上个元素
获取整个元素偏移量的方法(复制的情况需要自己来计算)
var range = window.getSelection().getRangeAt(0); var offset = 0; var str = ‘‘; var container = range.endContainer; console.log(container) var i=0; while(container.previousSibling){ // console.log(container.previousSibling.textContent.trim()); // console.log(container.previousSibling.textContent.trim().length); str += container.previousSibling.textContent.trim(); offset += container.previousSibling.textContent.trim().length; container = container.previousSibling; i++; // console.log(offset,container.previousSibling.textContent.trim().length) }
selection是对当前激活选中区(即高亮文本)进行操作。
在非IE浏览器(Firefox、Safari、Chrome、Opera)下可以使用window.getSelection()获得selection对象,本文讲述的是标准的selection操作方法。文中绝大部分内容来自 https://developer.mozilla.org/en/DOM/Selection
术语
以下几个名词是英文文档中的几个名词。
- anchor
- 选中区域的“起点”。
- focus
- 选中区域的“结束点”。
- range
- 是一种fragment(HTML片断),它包含了节点或文本节点的一部分。一般情况下,同一时刻页面中只可能有一个range,也有可能是多个range(使用Ctrl健进行多选,不过有的浏览器不允许,例如Chrome)。可以从selection中获得range对象,也可以使用document.createRange()方法获得。
属性
- anchorNode
- 返回包含“起点”的节点。
- anchorOffset
- “起点”在anchorNode中的偏移量。
- focusNode
- 返回包含“结束点”的节点。
- focusOffset
- “结束点”在focusNode中的偏移量。
- isCollapsed
- “起点”和“结束点”是否重合。
- rangeCount
- 返回selection中包含的range对象的数目,一般存在一个range,Ctrl健配合使用可以有多个。
方法
- getRangeAt(index)
- 从当前selection对象中获得一个range对象。
index:参考rangeCount属性。
返回:根据下标index返回相应的range对象。 - collapse(parentNode, offset)
- 将开始点和结束点合并到指定节点(parentNode)的相应(offset)位置。
parentNode:焦点(插入符)将会在此节点内。
offset: 取值范围应当是[0, 1, 2, 3, parentNode.childNodes.length]。
- 0:定位到第一个子节点前。
- 1:第二个子节点前。
- ……
- childNodes.length-1:最后一个子节点前。
- childNodes.length:最后一个子节点后。
- extend(parentNode, offset)
- 将“结束点”移动到指定节点(parentNode)的指定位置(offset)。
“起点”不会移动,新的selection是从“起点”到“结束点”的区域,与方向无关(新的“结束点”可以在原“起点”的前面)。
parentNode:焦点将会在此节点内。
Offset:1,parentNode的最后;0,parentNode的最前。 - modify(alter, direction, granularity)
- 改变焦点的位置,或扩展|缩小selection的大小
alter:改变的方式。”move”,用于移动焦点;”extend”,用于改变selection。
direction:移动的方向。可选值forward | backword或left | right
granularity:移动的单位或尺寸。可选值,character", "word", "sentence", "line", "paragraph", "lineboundary", "sentenceboundary", "paragraphboundary", or "documentboundary"。
Firefox 4 / Thunderbird 3.3 / SeaMonkey 2.1才会支持此函数, 官方文档:https://developer.mozilla.org/en/DOM/Selection/modify - collapseToStart()
- 将“结束点”移动到,selction的“起点”,多个range时也是如此。
- collapseToEnd()
- 将“起点”移动到,selction的“结束点”,多个range时也是如此。
- selectAllChildren(parentNode)
- 将parentNode的所有后代节点(parentNode除外)变为selection,页面中原来的selection将被抛弃。
- addRange(range)
- 将range添加到selection当中,所以一个selection中可以有多个range。
注意Chrome不允许同时存在多个range,它的处理方式和Firefox有些不同。 - removeRange(range)
- 从当前selection移除range对象,返回值undefined。
Chrome目前没有改函数,即便是在Firefox中如果用自己创建(document.createRange())的range作为参数也会报错。
如果用oSelction.getRangeAt()取到的,则不会报错。 - removeAllRanges()
- 移除selection中所有的range对象,执行后anchorNode、focusNode被设置为null,不存在任何被选中的内容。
- toString()
- 返回selection的纯文本,不包含标签。
- containsNode(aNode, aPartlyContained)
- 判断一个节点是否是selction的一部分。
aNode:要验证的节点。
aPartlyContained:true,只要aNode有一部分属于selection就返回true;false,aNode必须全部属于selection时才返回true。
以上是关于区域可编辑contenteditable的问题总结的主要内容,如果未能解决你的问题,请参考以下文章
实时监测contenteditable(可编辑文档)的内容发生改变
如何在具有 contentEditable 的元素上启用“可拖动”?
div设置contenteditable="true",即可编辑,我想做一个按钮,点击它之后,焦点处就自动出现一个可编辑的