Перезаписать выделенный текст при выделении текста мышью + HTML5 / jQuery - PullRequest
0 голосов
/ 26 марта 2019

У меня есть некоторый контент, сгенерированный моделью ML в сотнях абзацев, у каждого параграфа есть некоторый выделенный контент.

Иногда выделенные данные неверны, мы хотим, чтобы пользователь выделил текст и снова выделил его, чтобы исправить его.

<p> Contrary to popular belief, <span class='highlighted'>Lorem</span>Ipsum is not simply random text. It has roots in a piece of popular classical Latin literature from 45 <span class='highlighted'>BC</span>, making it over 2000 years old.</p>

В этом примерепользователь может выбрать:

  1. Lorem Ipsum
  2. Латиница
  3. 45 до н.э.
  4. 2000 лет

Нижекод работает для # 2 и # 4, но я не могу сделать это для # 1 и # 3, поскольку он уже выделен.

Я использую эту функцию getSelectionText () для выборатекст.

$('div.content>p').on('mouseup', function(e){
    var toselected = getSelectionText();
    var para = $(this).html();
    var start = para.indexOf(toselected);
    var end = start + toselected.length;
    var html = para.replace(toselected, '<span class="highlighted">' toselected + '</span>');
    var obj = {"content": $(this).text(), "indices_range":[[start, end]]}
    $.post('/update/<content_id>', data:tojson(obj), function(){        $(e.target).html(html);}) 

});

Также интересно, как я могу получить начальный, конечный индексы, если один и тот же текст встречается дважды или несколько раз, например.popular.

1 Ответ

1 голос
/ 29 марта 2019

Используйте Range и Selection API для управления выбором текстовых узлов. Вместо использования <span> используйте теги <mark>.
Причины использования <mark>

  • 100% семантика
  • Его использование встречается редко, что означает, что вероятность конфликтов CSS-селекторов очень мала.
  • По умолчанию он уже выделяет содержимое.

Использование: Выделите текст мышью, как обычно. <mark>s не гнездятся (это хорошо). Чтобы удалить выделенную область, щелкните по ней правой кнопкой мыши.

const mark = event => {
  const current = event.currentTarget;
  const target = event.target;
  const select = document.getSelection();
  if (event.which === 1) {
    const range = select.getRangeAt(0);
    const text = range.toString();
    const content = range.extractContents();
    const mark = document.createElement('MARK');
    mark.textContent = text;
    range.insertNode(mark);
  } else if (event.which === 3) {
    event.preventDefault();
    if (target.tagName === 'MARK') {
      const text = target.textContent;
      const tNode = document.createTextNode(text);
      target.parentNode.replaceChild(tNode, target);
    }
  }
  select.removeAllRanges();
  current.normalize();
  return false;
}

$(document).on("contextmenu mouseup", mark);
::selection {
  background: tomato;
  color: white;
}
<p> Contrary to popular belief, <mark>Lorem</mark>Ipsum is not simply random text. It has roots in a piece of popular classical Latin literature from 45 <mark>BC</mark>, making it over 2000 years old.</p>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
...