使用innerHTML和管道获取contenteditable div中的光标位置

使用innerHTML和管道获取contenteditable div中的光标位置,html,angular,contenteditable,caret,Html,Angular,Contenteditable,Caret,我正在Angular 5中编写一个简单的WYSIWYG编辑器来处理文本中的标记。这些标记类似于变量。例如,在执行以下操作时:Hi(!--username--),欢迎它呈现为嗨,亚历克斯,欢迎。为了方便非技术人员使用,WYSIWYG正在将(!--username-)转换为一个漂亮的HTML片段,在其内容中直接显示“Alexandre” 此编辑器还需要处理简单的HTML标记(,,…) 为此,我开发了一个名为editor的组件,它使用Angular的值访问器,并显示一个简单的div,如下所示: &

我正在Angular 5中编写一个简单的WYSIWYG编辑器来处理文本中的标记。这些标记类似于变量。例如,在执行以下操作时:
Hi(!--username--),欢迎它呈现为
嗨,亚历克斯,欢迎。为了方便非技术人员使用,WYSIWYG正在将
(!--username-)
转换为一个漂亮的HTML片段,在其内容中直接显示“Alexandre”

此编辑器还需要处理简单的HTML标记(
,…)

为此,我开发了一个名为editor的组件,它使用Angular的值访问器,并显示一个简单的div,如下所示:

  <div class="editor" #editor [innerHTML]="content | prettytags: completions" (focus)="toogleToolbar()" (focusout)="toogleToolbar()"
    (click)="onClick($event)" (keyup)="onKey($event)" [attr.contenteditable]="!readonly"></div>
为了让双向数据绑定像我使用[innerHTML]一样工作,我使用keyup事件来获取新字符,但我需要获取插入符号位置以附加新字符。为此,我复制/粘贴了堆栈溢出上的一个函数,以获取插入符号位置:

  private getCaretPosition() {
    const element = document.querySelector('.editor');
    const range = window.getSelection().getRangeAt(0);
    const preCaretRange = range.cloneRange();
    preCaretRange.selectNodeContents(element);
    preCaretRange.setEnd(range.endContainer, range.endOffset);
    return preCaretRange.toString().length;
  }
在我的onKeyUp上:我做了以下工作:

[...]
const position = this.getCaretPosition();
this.content += key.length === 1 ? this.content.slice(0, position) + key + this.content.slice(position) : '';
但当它得到文本位置时,它不起作用

例如,如果用户想要编辑内容:from
Hi(!--username--),欢迎
你好(!--username--),很高兴看到你回来
,他将插入符号放在逗号后面,因此我将得到
8
(对于“Hi alex”),但对于我的内容变量,我将得到
Hi(!--u

我知道我可以用HTML标记获得光标的位置,但是我需要为每个按下的键做很多计算


你有什么办法让这件事开始运作吗?

嗨,你解决了吗?嗨!是的。帮了我很多忙。你的项目有开放的github吗,急于检查你的项目,但我不能。这是一个商业项目。好的,不用担心。谢谢
[...]
const position = this.getCaretPosition();
this.content += key.length === 1 ? this.content.slice(0, position) + key + this.content.slice(position) : '';