Как создать простой маркер / маркер, учитывая интервалы столкновения тегов и элементы уровня блока? - PullRequest
1 голос
/ 16 января 2020

Я пытаюсь создать простой инструмент, который позволяет пользователю выбирать фрагмент текста на странице, чтобы он мог выделить то, что было выбрано . Я обнаружил, что могу начать решать эту проблему с помощью API Selection и Range . По сути, для выделения фрагмента используется следующий код:

function highlight(hl){
  var sel = window.getSelection();
  if(!sel || sel.iscollapsed || sel.rangeCount <= 0) return;
  
  var range = sel.getRangeAt(0);
  var hlWrap = document.createElement("span");
  hlWrap.classList.add(`highlighter-${hl}`);
  range.surroundContents(hlWrap);
}
.highlighter-1 ,
.highlighter-2 {
  border-radius: 2px;
  padding: 1px 1px;
  display: inline;
}

.highlighter-1 { background: rgb(254, 255, 171); }
.highlighter-2 { background: rgb(255, 171, 171); }
<button onclick="highlight(1)">HL1</button>
<button onclick="highlight(2)">HL2</button>
<div class="content">
<p>Phasellus dapibus congue nisi et dignissim. Mauris id pharetra elit, sit amet sagittis lorem. <span class="highlighter-1">Suspendisse
            sed quam in mi facilisis maximus.</span> Donec aliquet maximus risus sed cursus. Proin commodo interdum tortor, et
            mollis tellus luctus non. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus
            mus <img src="https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Fupload.wikimedia.org%2Fwikipedia%2Fcommons%2Fthumb%2Ff%2Ff3%2FEmoji_u1f435.svg%2F768px-Emoji_u1f435.svg.png&f=1&nofb=1" width="24px">. 
            <strong>Phasellus ornare sodales magna, id egestas nisi dictum quis.</strong> Interdum et malesuada fames ac ante ipsum
            primis in faucibus. <span class="highlighter-1">Phasellus non nibh sit</span> amet elit dignissim ullamcorper.</p>
<p>Nam in turpis viverra, cursus urna eget, vulputate sapien. Curabitur et mi convallis, sollicitudin felis
            <span class="highlighter-2">vitae, vestibulum sapien. Etiam a convallis sem, nec placerat leo. Curabitur rutrum magna enim,</span> eget blandit
            ipsum accumsan vel. Duis auctor tellus enim, id mollis risus egestas at. Cras at neque leo. Proin pretium
            semper facilisis. </p></div>

Это работает, но с жесткими ограничениями:

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

ПРИМЕЧАНИЕ: Предыдущие два элемента возвращают мне следующую ошибку:

Paused on exception
InvalidStateError: An attempt was made to use an object that is not, or is no longer, usable
Возможно применить один блик поверх другого (включая другой), не удаляя предыдущий. Результатом могут быть теги, вовлекающие других, бесконечно.

Я также хотел бы знать, как это возможно:

  1. Удалить выделенные разделы, не удаляя все, но только то, что выбрано .
  2. Добавить блики одного типа, если интервалы каким-либо образом сталкиваются. То есть я хочу смешивать / объединять блики одного типа, которые представляют один, если они добавляются вместе. Например:
Mauris <span class="highlighter-1">id</span><span class="highlighter-1"> pharetra elit, sit amet</span> sagittis lorem.

Я 3 дня искал это по inte rnet, и, к сожалению, я ничего не нашел. Кажется, что каждая поисковая система (здесь в стеке, google, duckduck go, youtube, wikipedia) представляет мне что-то с похожими терминами, но ссылаясь на другие темы. Это очень расстраивает. Английский sh не мой родной язык, и я не думаю, что знаю правильные термины для взвешивания. Пожалуйста, я не знаю, что делать дальше, и я очень хотел бы, чтобы кто-нибудь хотя бы дал мне хоть какой-то свет.

Если решение в чистом виде JavaScript или jQuery, это не имеет значения , оба очень приветствуются.

...