How to set caret position in a contenteditable after I append a span into it; and move caret...

Discussão em 'Angular' iniciado por Steve Chacko, Setembro 15, 2024.

  1. Steve Chacko

    Steve Chacko Guest

    I have a contenteditable that I am using for a chat application. When I tag a user, I find the current caretPosition and add a span to that location which is like this;

    <span class=\"highlight\" contenteditable=\"false\">${userName}</span>


    When I replace the tag with this span however, I lose focus of the contenteditable and the caret position is lost. I've tried looking at these answers,

    Answer 1 Answer 2

    but in both cases focus is lost, and if I set el.focus() before the setCursorPosition function, the caret just goes to the beginning of the contenteditable. my code;

    getCaretPositionInnerHTML() {
    var target = document.createTextNode("\u0001");
    document.getSelection().getRangeAt(0).insertNode(target);
    var position = this.contenteditable.nativeElement.innerHTML.indexOf("\u0001");
    target.parentNode.removeChild(target);
    return position;
    }

    saveMention(event, user): void { //lose focus after this
    event.stopPropagation();
    let tempString = this.contenteditable.nativeElement.innerHTML;
    let index = this.getCaretPositionInnerHTML();
    let replacement = this.getSpanFromUserFn(user);// returns the span in question
    let currentWordLength = this.getCurrentWord(tempString, index);// replace the current word with my span
    let newString = tempString.substring(0, index - currentWordLength.length) + replacement + tempString.substring(index + 1);
    this.contenteditable.nativeElement.innerHTML = newString;
    }

    ngOnChanges(changes: SimpleChanges) {
    if (this.caretPosition) {
    console.log(changes);
    this.selection.removeAllRanges();
    let range = this.setCursorPosition(this.element.nativeElement, document.createRange(), { pos: this.caretPosition, done: false});
    this.element.nativeElement.focus();
    range.collapse(true);
    this.sel.addRange(range);
    }

    //find the child node and relative position and set it on range
    setCursorPosition(parent, range, stat) {
    if (stat.done) return range;
    if (parent.childNodes.length == 0) {
    if (parent.textContent.length >= stat.pos) {
    range.setStart(parent, stat.pos);
    stat.done = true;
    } else {
    stat.pos = stat.pos - parent.textContent.length;
    }
    } else {
    for (var i = 0; i < parent.childNodes.length && !stat.done; i++) {
    this.currentNode = parent.childNodes;
    this.setCursorPosition(this.currentNode, range, stat);
    }
    }
    return range;
    }

    Continue reading...

Compartilhe esta Página