zoukankan      html  css  js  c++  java
  • 区域可编辑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。
  • 相关阅读:
    Spring@Profile注解
    day 32 子进程的开启 及其用法
    day 31 udp 协议SOCK_DGRAM
    day 30 客户端获取cmd 命令的步骤
    day 29 socket 理论
    day 29 socket 初级版
    有关 组合 继承
    day 27 多态 接口 类方法 静态方法 hashlib 摘要算法模块
    新式类和经典类的区别
    day 28 hasattr getattr serattr delattr 和带__内置__ 类的内置方法
  • 原文地址:https://www.cnblogs.com/yiyi17/p/9161740.html
Copyright © 2011-2022 走看看