Content Editable Div - Как обернуть совпадающее слово в элементе span при вводе текста и с учетом положения курсора - PullRequest
0 голосов
/ 10 июля 2020

Я создаю специальное поле редактируемого содержимого, где я могу легко выделить или заменить определенные зарезервированные тексты, если они совпадают с их указанными командами c. Он включает в себя упоминания (@), хэштеги (#) и некоторые слова, такие как «высокий», «средний» и «низкий», цвета которых будут изменены при совпадении.

Например, если пользователь вводит текст " high ", то что нужно сделать, это инкапсулировать этот тег in span с некоторыми стилями на нем и поместить курсор только в конце этого конкретного слова.

Проблема, с которой я столкнулся, связана с положение каретки после замены этого слова, поскольку оно всегда устанавливается в конец предложения, даже если я печатаю где-то посередине.

Вот мой HTML код:

<div id="textBox" contenteditable="true" class="c-edit-container">
</div>

А это JS:

let containerEl = document.getElementById('textBox')

function getWordPrecedingCaret() {
    let _selection = window.getSelection();
    if (!_selection.rangeCount) return;
    let _range = _selection.getRangeAt(0).cloneRange();
    _range.collapse(true)
    _range.setStart(containerEl, 0);

    var words = _range.toString().split(' '),
        lastWord = words[words.length - 1];
    if (lastWord && lastWord == 'high') {
        var wordStart = _range.toString().lastIndexOf(lastWord);
        var wordEnd = wordStart + lastWord.length;

        _range.setStart(_selection.focusNode, wordStart);
        _range.setEnd(_selection.focusNode, wordEnd);
        _range.deleteContents();
        let el = document.createElement('span');
        el.style.color = 'red';
        el.contentEditable = false;
        el.innerHTML = 'high';
        _range.insertNode(el);
        _range.setStartAfter(el)
    }
}

containerEl.addEventListener('keyup', getWordPrecedingCaret);
containerEl.addEventListener('click', getWordPrecedingCaret);
...