• 区域可编辑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="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:最后一个子节点后。
    Mozilla官方文档 中讲到取值为0和1,经测试不准确。文档中还有一句不是十分清楚“The document is not modified. If the content is focused and editable, the caret will blink there.”
    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。
  • 相关阅读:
    markdown语法
    基于Vue 使用threejs导入gltf动画模型
    创建Vue项目
    一个简单的特效
    网页五--html插入表格
    网页四--按钮反应
    网页三
    简单的页面
    一个能实现超链接的最简单程序
    计算机基本配置和作用
  • 原文地址:https://www.cnblogs.com/yiyi17/p/9161740.html
Copyright © 2020-2023  润新知