Выделить фрагмент текста, выбранный пользователем

#javascript #html

#javascript #HTML

Вопрос:

У меня есть <div>with some text<div> и мне нужно выделить фрагмент текста, выбранный пользователем.

Я частично реализовал это: вот мой код

 thisRespondHightlightText(".container");


function thisRespondHightlightText(thisDiv){
    $(thisDiv).on("mouseup", function () {
        var selectedText = getSelectionText();
        var selectedTextRegExp = new RegExp(selectedText,"g");
        var text = $(this).text().replace(selectedTextRegExp, "<span class='highlight'>"   selectedText   "</span>");
        $(this).html(text);
    });
}

function getSelectionText() {
    var text = "";
    if (window.getSelection) {
        text = window.getSelection().toString();
    }
    return text;
}  
 .highlight {
    background-color: orange;
}
      
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</div>  

Тем не менее, я застрял в решении следующих проблем:

  1. Мне нужно выделить точный фрагмент, выбранный пользователем, даже если в тексте есть несколько совпадений. Например, если пользователь выбирает вторую букву t в <div>with some text<div> , должна быть выделена только она t , а не все из них или первая.

проблема 1

  1. Когда пользователь выбирает полный текст, он не выделяется, но остается выделенным.

проблема 2

  1. Как мне реализовать это для мобильных устройств? Проблема в том, что mouseup событие не запускается.

Комментарии:

1. вы пробовали с сенсорными событиями

2. @prasanth touchend не работает 🙁

3. попробуйте эти события on("touchend touchmove touchcancel mouseup" .на моем мобильном он работает

4. что касается ваших первых двух проблем, проверьте другие свойства, которые предоставляет объект выделения , помимо toString() . Что касается вашей третьей проблемы, ознакомьтесь с selectionchange .

Ответ №1:

Обновить

Выделение amp; Диапазон API

В следующей демонстрации используется следующее:

Selection API
.getSelection()
.getRangeAt()
Range API
.extractContents()
.insertNode()
Разное
.createElement()
.appendChild()
.ctrlKey
.textContent
.tagName
.parentNode
.removeChild()
.createTextNode()

Просто select text ctrl (Mac: select text ^), и он обернет <mark> тег вокруг выделенного текста. Чтобы удалить выделение click alt (Mac: click )


Демонстрация 1

API выбора и диапазона

 function mark(e) {
  if (e.ctrlKey) {
    var sel = document.getSelection();
    var rng = sel.getRangeAt(0);
    var cnt = rng.extractContents();
    var node = document.createElement('MARK');
    node.style.backgroundColor = "orange";
    node.appendChild(cnt);
    rng.insertNode(node);
    sel.removeAllRanges();
  }
}

function unmark(e) {
  var cur = e.currentTarget;
  var tgt = e.target;
  if (tgt.tagName === 'MARK') {
    if (e.altKey) {
      var txt = tgt.textContent;
      tgt.parentNode.replaceChild(document.createTextNode(txt), tgt);
    }
  }
  cur.normalize();
}

document.addEventListener('keyup', mark); // ctrl keyup
document.addEventListener('mouseup', mark);// ctrl mouseup
document.addEventListener('click', unmark); // alt click  
 ::selection {
  background: orange
}  
 <P>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
  in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</P>  


::selection

Попробуйте использовать псевдоэлемент ::selection


Демонстрация 2

 ::selection {
  background: orange;
}  
 <P>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
  in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</P>  

Комментарии:

1. Спасибо за ответ, я не знал об этом псевдоэлементе, в моем случае это будет полезно для улучшения пользовательского опыта. Однако мне нужно, чтобы этот текст оставался выделенным даже после того, как узел потеряет фокус. Итак, похоже, что манипулирование DOM — это единственный способ.

2. Действительно, DOM — это единственный способ получить постоянный focus , вы, вероятно, могли бы получить что-то более надежное, используя API диапазона и выбора

3. Есть комнаты для чатов. Все, что нам нужно сделать, это достаточно пообщаться, и нам будет предложено присоединиться….

4. @NikitaMarinosyan добавлена функция удаления. Просто нажмите ctrl на отмеченной области.

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