Как получить определенный выбор из contenteditable

То, что я пытаюсь сделать, это получить выбор только для слова, которое я хочу, из входных данных, доступных для редактирования. Например,

Привет, мой мир

из приведенного выше входного значения я хочу выбрать только слово «Мой» и получить его строковое значение.

до сих пор я написал функцию, которая получает выбор до каретки из диапазона 0, например:

function selectUptoCaret(el){
    var range = window.getSelection().getRangeAt(0);
    var preCaretRange = range.cloneRange();
    preCaretRange.selectNodeContents(el);
    preCaretRange.setEnd(range.endContainer, range.endOffset);

    var sel = window.getSelection()
    sel.removeAllRanges()
    sel.addRange(preCaretRange)
  }

Когда я нажимаю «y» в слове «Мой», он выбирает «Привет, мой». но опять же, я хочу выбрать только «Мой», а не «Привет, мой».


person Jay Jeong    schedule 03.01.2019    source источник


Ответы (1)


Я думаю, что вы в основном там, но проблема, с которой вы сталкиваетесь, когда все слева от курсора выделено, вероятно, связана с тем фактом, что вы не вызываете preCaretRange.setStart(), и поэтому он думает, что начало должно быть нулем. Я немного изменил вашу функцию, чтобы заставить ее выбирать фактическое слово, в котором находится ваш курсор:

function selectUptoCaret(el){
    var range = window.getSelection().getRangeAt(0);
    var preCaretRange = range.cloneRange();

    var startOffset = range.startContainer.textContent.lastIndexOf(' ', range.startOffset);
    var endOffset = range.endContainer.textContent.indexOf(' ', range.endOffset);

    preCaretRange.selectNodeContents(el);
    preCaretRange.setStart(range.startContainer, ~startOffset ? startOffset + 1: 0);
    preCaretRange.setEnd(range.endContainer, ~endOffset ? endOffset : range.endContainer.textContent.length);

    var sel = window.getSelection()
    sel.removeAllRanges()
    sel.addRange(preCaretRange)
}

Я предполагаю, что параметр el, переданный в selectUptoCaret, является фактическим HTML-элементом contentEditable.

Мои изменения были:

  • взять позицию курсора и получить позицию следующего и предыдущего пробелов
  • если нет предыдущего пробела (определяется проверкой ~startOffset), мы начнем с 0, потому что мы находимся в первом слове
  • если нет следующего пробела (определяется проверкой ~endOffset), мы будем использовать полную длину текстового содержимого, потому что мы находимся в последнем слове.
  • установите setStart на наш объект preCaretRange, чтобы убедиться, что у нас есть конечная начальная точка, которая не обязательно является началом текстового содержимого

Примечание: моя тройка ~startOffset ? startOffset + 1 : 0 эквивалентна выражению startOffset > -1 ? startOffset + 1 : 0. Использование побитового оператора ~ является удобным способом проверки того, что значение не равно -1 (начиная с ~ -1 === 0).

Теперь это будет выбирать только текущее слово в позиции курсора.

person Ryan Dabler    schedule 07.01.2019