Как проверить, не переливается ли выделенный текст в определенный класс - PullRequest
2 голосов
/ 07 мая 2020

Контекст:

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

На моем сайте пользователи могут создавать свои собственные статьи. В этих статьях пользователи могут выделять текст и комментировать его. Возьмем, к примеру, этот текст:

Lorem ipsum dolor sit amet conctetur adipiscing elit sed do eiusmod

Если бы это была статья пользователя, я бы мог go выделить и выделить текст «Lorem ipsum», например:

" Lorem ipsum dolor sit amet conctetur adipiscing elit sed do eiusmod."

Это создает класс вокруг выделенного текста, для которого background-color установлено значение grey.

На этом этапе я хочу запретить пользователю выделять любой текст, который уже был выделен («Lorem ipsum»), потому что у меня возникают проблемы с правильным выделением слов, которые являются частью более чем одного выделения. .

Итак, мне нужна система, в которой, когда пользователь делает выделение, включающее любую часть текста, которая уже содержится в классе, например:

"Lorem ipsum dolor sit amet conctetur adipiscing elit sed do eiusmod "

С выделением« ipsum dolor », включая« ipsum », который уже был выделен и уже имеет имя класса

Это затем всплывает предупреждение, а выделение не делается.

То, что я пробовал до сих пор:

Я уже пробовал использовать настройку свойства css user-select: none;

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

Вопрос и пример JSFiddle:

Как узнать, содержит ли выделенный текст текст из определенного класса?

Вот пример того, что я хочу, когда пользователь выделяет текст, содержащийся в другом классе:

$("div").click(function() {
    checkIfTextisAlreadyHighlighted();
});

function checkIfTextisAlreadyHighlighted() {
	  var sel = window.getSelection();
    if (sel) {
  	    alert("This text contains the class *class name here* and cannot be highlighted.");
    }
}
.highlighted {
    background-color: lightGrey;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
  <span class='highlighted'>Selecting this text should make this message appear if text that already contains class is highlighted</span>. More random text.
</div>

Ответы [ 2 ]

4 голосов
/ 09 мая 2020

Некоторые пояснения к следующей реализации:

  1. Извлечь выделение и получить диапазон.
  2. Как только у вас есть диапазон - проверьте, являются ли начало и конец одним и тем же узлом ( если это так - мы не получим элемент контейнера, и поэтому нет имени класса, которое мы можем проверить снова - нам нужно проверить, есть ли у родителя соответствующий класс).
  3. Если у нас есть несколько элементов в нашем выборе - мы можем проверить, имеют ли клонированные элементы тот класс, который нам нужен (с помощью querySelector).
  4. (Это не было частью вопроса) - вы также можете удалить выделение, если оно вам нужно.

Вот рабочий пример:

$("div").mouseup(function() {
    checkIfTextisAlreadyHighlighted();
});

function resetSelection() {
  window.getSelection().removeAllRanges();
}

function checkIfTextisAlreadyHighlighted() {
    const classToSearch = 'highlighted';
    const sel = window.getSelection();
    const range = sel.getRangeAt(0);
    if (range.startContainer === range.endContainer && range.startContainer.parentElement.classList.contains(classToSearch)) {
        alert(`This text contains the class ${classToSearch} and cannot be highlighted.`);
        resetSelection();
    } else {
        if (range.cloneContents().querySelector(`.${classToSearch}`) !== null) {
            alert(`This text contains the class ${classToSearch} and cannot be highlighted.`);
            resetSelection();
        }
    }
}
.highlighted {
    background-color: lightGrey;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
  <span class='highlighted'>Selecting this text should make this message appear if text that already contains class is highlighted</span>.
  More random text.
  <span class='highlighted'>Selecting this text should make this message appear if text that already contains class is highlighted</span>.
  More random text.
</div>
0 голосов
/ 13 мая 2020

Если вы просто хотите, чтобы пользователь не выбирал указанный c выделенный текст, вы можете добавить user-select: none; своему классу.

.highlighted {
  background-color: grey;
  user-select: none;
  -webkit-user-select: none;
  -ms-user-select: none;
  -moz-user-select: none;
}
<span class="highlighted">Lorem ipsum</span> dolor sit amet consectetur adipiscing elit sed do eiusmod.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...