How to get linebreak location from DOM element using JavaScript

Viewed 447

In my HTML page, I have long text that has some auto-generated linebreaks at certain words (using line-break: normal), now a JavaScript library (vue-typer) types the same text but does line breaks at certain characters and doesn't support breaking the text at words.

So I wanted to fetch all linebreaks locations from the default HTML text and insert them into the vue-typer string so it will do line breaks at the same place.

So the question becomes: How to get the location of a linebreak from a DOM text?

1 Answers

Idea: Identify each line with its Y-position.

Here is a simple algorithm, I followed^

  • wrap up each word with an element, in order to use JS.
  • then, apply .offsetTop property on each word to get its Y-position.
  • now, loop up on every element and group them based on their Y-position, i.e., extract lines.
  • lastly, the position of line-breaks are simply the "end of each line", hence it is line.length

let p = document.querySelector('p');
p.innerHTML = '<span>' + p.innerHTML.split(' ').join(' </span><span>') + '</span>'; // add spans in b/w

let spans = [...p.querySelectorAll('span')];
let initY = spans[0].offsetTop; // get the offsetTop for first line

let lines = [''], idx = 0, i; 
for(i = 0; i < spans.length; i++) {
  if(spans[i].offsetTop - initY > 2) {
    initY = spans[i].offsetTop; // reset the Y
    lines.push(''); // add starting of line
    idx++; // move to next line
  }
  lines[idx] += spans[i].innerText; // add the text everytime
}

let breaks = lines.map((val, idx) => [idx, val.length]);
// ^ get (row, col) pairs
console.log(breaks);
p {
  line-break: normal;
}
span {
  display: inline-block;
  white-space: pre;
}
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum felis elit, scelerisque id rhoncus et, hendrerit nec turpis. Phasellus eget condimentum justo. Aliquam porta, risus sed elementum hendrerit, turpis urna posuere libero, eget facilisis sem purus sed mi. Nulla pulvinar nibh quis bibendum lacinia. Aenean eu nibh pharetra, imperdiet mi eget, vehicula mauris. In hac    habitasse platea dictumst. Phasellus ante enim, bibendum quis turpis a, volutpat auctor mi. Mauris scelerisque sem a ornare dignissim. Nullam in sem ac turpis aliquet dictum sit amet dignissim est.</p>

^: Many thanks to user GetSet, who helped me in developing the idea :)

Related