Получить каждую строку выделения текста

У меня есть текстовый блок фиксированной ширины, и я пытаюсь получить каждую строку текста boundingClientRect. Мне интересно, есть ли у Выбор API метод для этого, который я просто пропустил. Есть ли простой способ получить каждую строку выделенного текста?

В настоящее время единственное решение, которое я могу придумать, - это создать диапазоны вокруг каждого символа в выборе, а затем объединить символы, если они имеют одинаковую координату y в их ограничивающем клиентском прямоугольнике. Это очень неэффективно, поэтому мне любопытно, есть ли более простой метод.

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

Получить каждую строку выделения текста

Выбор будет всегда текстовым. Так что не нужно беспокоиться об изображениях. Однако они могут быть в разных элементах, но они будут одного типа тегов (например, без ссылок или тегов em/strong).

Возвращает выделенный блок текста

const selection = window.getSelection().getRangeAt(0);

В МаркДжс есть решение для выделения, заключающее все в один тег.

<mark><p>hello there</p></mark>

Мой план состоял в том, чтобы использовать аналогичный алгоритм, чтобы получить внутренний html и пройтись по каждому символу и обернуть его новым тегом с именем класса, который затем можно было бы найти, а затем вычислить ограничивающую рамку. Это просто написать, но кажется более сложным в вычислительном отношении, чем мне бы хотелось.

Есть ли способ просто получить ограничивающую рамку каждой строки?

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
0
78
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вместо этого вы можете использовать getClientRects:

var selectionDivs = [];

document.addEventListener('selectionchange', function () {
  var range = window.getSelection().getRangeAt(0);
  var rects = range.getClientRects();
  selectionDivs.forEach(function (div) {
    div.remove();
  });
  selectionDivs = [];
  for (var i = 0; i < rects.length; i++) {
    var div = document.createElement('div');
    div.className = 'rect';
    div.style.left = (window.scrollX + rects[i].left) + 'px';
    div.style.top = (window.scrollY + rects[i].top) + 'px';
    div.style.width = rects[i].width + 'px';
    div.style.height = rects[i].height + 'px';
    document.body.appendChild(div);
    selectionDivs.push(div);
  }
});
.rect {
  position: absolute;
  pointer-events: none;
  border: 1px solid black;
}
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Nunc sed velit dignissim sodales ut eu. Imperdiet sed euismod nisi porta lorem mollis. Nisl suscipit adipiscing bibendum est. Elit eget gravida cum sociis natoque penatibus et. Mauris in aliquam sem fringilla. In arcu cursus euismod quis viverra. Imperdiet sed euismod nisi porta lorem mollis. Eget gravida cum sociis natoque penatibus et. Sed libero enim sed faucibus turpis in eu mi bibendum. Varius duis at consectetur lorem donec massa. Facilisi nullam vehicula ipsum a arcu. Libero justo laoreet sit amet cursus sit. At in tellus integer feugiat scelerisque varius morbi. Est ullamcorper eget nulla facilisi etiam. Semper eget duis at tellus at urna condimentum mattis.

Это работает! Я очень надеялся, что есть простое решение этой проблемы. Рад видеть, что есть. Спасибо за помощь.

Josh Ferrell 10.04.2019 18:01

Рад, что это полезно!

Steve 10.04.2019 18:02

Другие вопросы по теме