相当于 angular2 中的 surroundContents

equivalent of surroundContents in angular2

我想在 angular 中使用与 renderer2

等效的 surroundContents()

将插入符放在可编辑的特定位置 div 我希望 onClick() 将前一个字符包装在一个范围内 (我假设点击时插入符号的位置不会随 preventdefault 而改变)

onChaining(event) {
      const caretPosition = window.getSelection().getRangeAt(0);
      const range = document.createRange();
      range.setStart(caretPosition.commonAncestorContainer, caretPosition.startOffset - 1);
      range.setEnd(caretPosition.commonAncestorContainer, caretPosition.endOffset );

      const wrap= this.renderer.createElement('span');
      range.surroundContents(wrap);

}

我想使用 renderer2 而不是 surroundContents 并拥有新的 dom 参考,以便我可以回滚并在需要时删除环绕。

插入符号的位置未知(在文本节点中),因此不存在以前的引用。

好吧,似乎 Renderer2 期望父对象具有方法 appendChild()。所以你不能使用像 this.renderer.appendChild(range,wrap)insertBefore 这样的东西。但是仍然有可能实现不可撤销的行为。根据 documentation surrondContents:

This method is nearly equivalent to newNode.appendChild(range.extractContents()); range.insertNode(newNode); So we repeat the mentioned behavior and will keep the range and a clone of a selected text node.

changes: {
  range: Range;content: Node
}[] = [];

render() {
  const caretPosition = window.getSelection().getRangeAt(0);
  const range = document.createRange();
  range.setStart(
    caretPosition.commonAncestorContainer,
    caretPosition.startOffset - 1
  );
  range.setEnd(
    caretPosition.commonAncestorContainer,
    caretPosition.endOffset
  );

  const wrap = this.renderer.createElement("span");
  this.renderer.setStyle(wrap, "background-color", "red");
  const contents = range.extractContents();

  this.changes.push({
    range: range,
    content: contents.cloneNode(true)
  });
  this.renderer.appendChild(wrap, contents);
  range.insertNode(wrap);
}

undo() {
  const action = this.changes.pop();
  const range = action.range;
  const node = range.extractContents();
  range.insertNode(action.content);
}

这里是 Stackblitz sample