Получить текст конкретной строчки
const Lines = (el, l, lines = [], last = 0, s = 0) => {
el.append(cl = document.createElement('div'));
el.textContent.split("").forEach(v => {
cl.innerHTML += v;
last != (last = cl.offsetHeight) && s++;
lines[s] = (lines[s] ?? '') + v;
if(lines[l+1])
cl.remove();
});
console.log(lines[l]);
};
Lines(text, 3);
window.onresize = _ => Lines(text, 3);
#text {
white-space: pre-wrap;
max-width: 40%
}
<div id=text>
Lorem ipsum dolor sit, amet consectetur adipisicing elit.
Praesentium nemo dolores debitis, maxime quia ipsum quasi
officiis id libero tenetur autem similique iure itaque optio quis beatae minima! Libero, eaque!
</div>
Ни как не удается выхватить текст конкретной строчки. На выходе получаю текст но он то обрезан сначала, то сканца. Как мне решить это?
В моем случаи вытаскивает
tur adipisicing elit.
Вместо
consectetur adipisicing elit.
Ответы (1 шт):
Придумал такой алгоритм:
Рзабиваем текст по пробелам
Объявляем массив
lineи складываем туда по одному слова из разбиенияСоздаём временный
div, куда каждый раз вводим объединение всех слов изlineи смотрим на его ширину. Стили уdiv-а такие, чтобы при добавлении и удалении не было видно этого визуально. Не использовалdisplay: none, т.к. тогда не будет размера уdiv-а, а так можно будет настроить ему такие же стили как у основногоdiv-а и более корректно определять допустимую ширину и прочие данныеПока ширина меньше чем у основного
div-а, то просто продолжаем добавлять слова. Если ширина станет больше чем у основногоdiv-а, то объединяем все слова, кроме последнего в одну сроку и добавляем в массив строкПоследнее слово сразу становится первым словом для следующего предложения
После окончания цикла смотрим, если
line, не пустой, значит осталось последнее предложение и его просто добавлем в массивlinesТ.к. количество строк может меняться постоянно, то при отсутсвии строки под нужным индексом, просто возвращается последняя строка
const getLine = (target, index) => {
const lines = [];
const separatorSymbol = ' ';
const words = target.textContent.trim().split(separatorSymbol);
const targetWidth = target.offsetWidth;
const tempDiv = document.createElement('div');
tempDiv.style = 'visibility: hidden; position: absolute; width: fit-content';
document.body.append(tempDiv);
let line = [];
for (const word of words) {
line.push(word);
tempDiv.innerHTML = line.join(separatorSymbol);
const currWidth = tempDiv.offsetWidth;
if (currWidth <= targetWidth) continue;
const lastWord = line.pop();
lines.push(line.join(separatorSymbol));
line = [lastWord];
}
if (line.length !== 0) lines.push(line.join(separatorSymbol));
tempDiv.remove();
return lines[index] ?? lines[lines.length - 1];
};
console.log(getLine(text, 3));
window.onresize = _ => console.log(getLine(text, 3));
#text {
white-space: pre-wrap;
max-width: 40%
}
<div id=text>
Lorem ipsum dolor sit, amet consectetur adipisicing elit. Praesentium nemo dolores debitis, maxime quia ipsum quasi officiis id libero tenetur autem similique iure itaque optio quis beatae minima! Libero, eaque!
</div>
Код может показаться рабочим, но это далеко не так. Алгоритм будет неправильно работать например если вручную расставлять переносы строк или изменить правило переноса в основном div-е или ещё что-то. Универсального способа не придумал, но конкретно под эти правила можно этот алгоритм использовать
А ещё не нравится постоянно добавлять и удалять div из DOM-а, наверное точно зная шрифт и размеры каждого символа, можно просто вычислить ширину. Для небольшой оптимизации можно ещё объявление tempDiv и назначение стилей вынести за пределы getLine, чтобы каждый раз не создавать его
