【问题标题】:How to set caret position of a contenteditable div containing combination of text and element nodes如何设置包含文本和元素节点组合的内容可编辑 div 的插入符号位置
【发布时间】:2016-11-24 08:22:09
【问题描述】:

我的 HTML:

<div id="text" contenteditable="true">abcd<img src="icon.gif"/>efgh</div>

我的caret = 5; 所以我想将插入符号的位置设置在图像之后,因为图像被视为 1 个字符。

所以我写了这个代码:

var node = document.querySelector("div");
node.focus();
var textNode = node.firstChild;
var caret = 5; 
var range = document.createRange();
range.setStart(textNode, caret);
range.setEnd(textNode, caret);
var sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);

但我收到此错误:

未捕获的 DOMException:无法在“Range”上执行“setStart”:偏移量 5 大于或等于节点的长度 (4)。

请建议我如何实现这一目标?在我想要的插入符号位置之前,我可能有几张图片,每张图片都将被视为 1 个字符。

【问题讨论】:

    标签: javascript contenteditable caret


    【解决方案1】:

    您的 textNode 有 3 个孩子(1 个文本、1 个元素、1 个文本),因此您不能只使用 firstChild

    您需要遍历&lt;div&gt;childNodes 并跟踪childNodenodeType 等于Node.TEXT_NODE 的字符数(参见MDN 上的here)。如果字符数小于caret 的值,您可以从caret 中扣除该值并移至下一个文本节点。

    根据您的条件:

    我希望每张图片都被视为 1 个字符

    代码将从caret 中减去1,其中nodeType == 1Node.ELEMENT_NODE

    这是一个带有多个图标的代码示例:

    var node = document.querySelector("div");
    node.focus();
    var caret = 24; 
    
    var child;
    var childNodeIndex = 0;
    for(var i=0; i<node.childNodes.length; i++) {
      child = node.childNodes[i];
      // Node.ELEMENT_NODE == 1
      // Node.TEXT_NODE == 3
      if(child.nodeType == Node.TEXT_NODE) {
        // keep track of caret across text childNodes
        if(child.length <= caret) {
          caret -= child.length;
        } else {
          break;
        }
      } else if (child.nodeType == Node.ELEMENT_NODE) {
        // condition that 'each image would be treated as 1 character'
        if(caret > 0) {
          caret -= 1;
        } else {
        	break;
        }
      };
      childNodeIndex += 1;
    }
    
    var textNode = node.childNodes[childNodeIndex];
    
    // your original code continues here...
    var range = document.createRange();
    range.setStart(textNode, caret);
    range.setEnd(textNode, caret);
    var sel = window.getSelection();
    sel.removeAllRanges();
    sel.addRange(range);
    &lt;div id="text" contenteditable="true"&gt;a&lt;img src="https://www.splitbrain.org/_static/ico/circular/ico/add.png"/&gt;&lt;img src="https://www.splitbrain.org/_static/ico/circular/ico/add.png"/&gt;&lt;img src="https://www.splitbrain.org/_static/ico/circular/ico/add.png"/&gt;&lt;img src="https://www.splitbrain.org/_static/ico/circular/ico/add.png"/&gt;b&lt;img src="https://www.splitbrain.org/_static/ico/circular/ico/add.png"/&gt;cdefghijkl&lt;img src="https://www.splitbrain.org/_static/ico/circular/ico/add.png"/&gt;mnopq&lt;img src="https://www.splitbrain.org/_static/ico/circular/ico/add.png"/&gt;rst&lt;img src="https://www.splitbrain.org/_static/ico/circular/ico/add.png"/&gt;uvw&lt;img src="https://www.splitbrain.org/_static/ico/circular/ico/add.png"/&gt;xyz&lt;img src="https://www.splitbrain.org/_static/ico/circular/ico/add.png"/&gt;&lt;/div&gt;

    【讨论】:

      猜你喜欢
      • 2017-04-06
      • 1970-01-01
      • 2020-07-24
      • 1970-01-01
      • 1970-01-01
      • 2011-05-03
      • 1970-01-01
      • 2011-04-27
      • 1970-01-01
      相关资源
      最近更新 更多