Перед использованием getBoundingClientRect
необходимо знать эту заметку :
Рабочий проект CSSOM указывает, что он возвращает ClientRect для каждого поля границы
И под этим «стандартом»:
Для встроенного элемента два определения одинаковы. Но для блочного элемента Mozilla вернет только один прямоугольник.
Поэтому, если кто-то, читающий этот пост, хочет найти общее решение для более точных позиций и макетов выбранных текстов, я предлагаю следующие подходы:
Вариант 1: Найти точную начальную и конечную точку текста с помощью , вставив невидимые элементы . Затем вычислите выбранные прямоугольники линии с извлеченной вычисленной высотой линии и шириной контейнера. Используемые API: window.getComputedStyle .
- Pro: результат будет наиболее точным для каждой строки текста.
- Con: 1) Если выделение происходит между несколькими узлами с разной высотой и шириной линии, алгоритм становится сложным. 2) И вам необходимо реализовать алгоритм вычислений, который занимает слишком много времени при реализации простой функции.
Вариант 2: Оберните каждый текст тщательно разработанным внутренним элементом, извлекая
расположение каждого блока и объединение результатов в строки.
- Pro: работает для всех непрерывных выборов (это в основном означает все случаи в текущих реализациях основного браузера). Достаточно хорошая точность для каждой строки текста.
- Con: 1) В некоторых случаях его результат немного неточен, так как добавляет ширину ошибки kerning . 2) Это медленно на очень большой выбор текстов.
Для варианта 2 rangeblock - это существующая реализация с простым API, который дает вам абсолютный макет каждой строки текста:
let block = rangeblock.extractSelectedBlock(window, document);
console.info("Text layout: " + JSON.stringify(block.dimensions));
// output: Text layout: {Left: 100, Top: 90, Width: 200, Height: 50}