0

我试图在跨越多个 div 的选定文本之前和之后放置文本。例如,如果文本是

  <p>This is a random text<p>
  <p>Another random text<p>

现在如果用户从两个 p 标签中选择“是一个随机文本另一个随机文本”。输出应该是

  <p>This hello world is a random text hello world<p>
  <p>hello world Another random text hello world<p>

我知道如何在所选文本之前和之后放置文本,但是如何在每个 p 结尾之前和另一个选定 p 标签的开始之后插入文本。

function surroundSelection(textBefore, textAfter) {
if (window.getSelection) {       
        var range = sel.getRangeAt(0);
        var startNode = range.startContainer, startOffset = range.startOffset;
        var boundaryRange = range.cloneRange();
        var startTextNode = document.createTextNode(textBefore);
        var endTextNode = document.createTextNode(textAfter);
        boundaryRange.collapse(false);
        boundaryRange.insertNode(endTextNode);
        boundaryRange.setStart(startNode, startOffset);
        boundaryRange.collapse(true);
        boundaryRange.insertNode(startTextNode);

        // Reselect the original text
        range.setStartBefore(startTextNode);

        range.setEndAfter(endTextNode);
        sel.removeAllRanges();
        sel.addRange(range);
  }
}

这只是在所选文本之前和之后添加文本,而与标签无关。

4

1 回答 1

0

您可以使用Range.extractContents删除选择并将其添加到 DocumentFragment。然后您可以循环遍历children、更改textContent并使用Range.insertNode将它们添加回父元素。

这是一个例子。

提取内容后必须从剩余的空元素中清理父元素p,不知道如何在没有额外清理功能的情况下做到这一点。似乎extractContents只提取文本节点并将空元素留在 DOM 中,但我可能错了。

var btn = document.getElementsByTagName("button");

function cleanUpEmptyElem (collection, parent) {
  collection.forEach(function(elem) {
    if(elem.textContent.length < 1) {
      parent.removeChild(elem);
    }
  })
}

function surroundSelection (selection) {
  var range = selection.getRangeAt(0);
  if (range.commonAncestorContainer.nodeType !== 3) {
    [].slice.call(range.extractContents().children).forEach(function(elem) {
      elem.textContent = "Foo " + elem.textContent + " Bar";
      range.insertNode(elem);
    });
    cleanUpEmptyElem([].slice.call(range.commonAncestorContainer.children), range.commonAncestorContainer)
  } else {
    range.commonAncestorContainer.parentElement.textContent = "Foo " + range.commonAncestorContainer.parentElement.textContent + " Bar";
  }
  range.detach();
  selection.removeAllRanges();
}


btn[0].addEventListener("click", function() {
  if (window.getSelection && window.getSelection().rangeCount) {
    surroundSelection(window.getSelection());
  } else {
    console.log("either nothing is selected or window.getSelection is not available")
  }
}, false)
button {
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
}
<div>
  <p>This is a random text</p>
  <p>Another random text</p>
  <p>More random text</p>
  <p>Another random text</p>
</div>

<button>insert text in selected elements</button>

于 2016-05-05T21:42:02.123 回答