-1

I'm using the code below, written by Niels Reijnders on this thread Wrap each line of paragraph in a span to wrap each line of a paragraph in span.

function splitLines(container, opentag, closingtag) {
  var spans = container.children,
    top = 0,
    tmp = '';
  container.innerHTML = container.textContent.replace(/\S+/g, '<n>$&</n>');
  for (let i = 0; i < spans.length; i++) {
    var rect = spans[i].getBoundingClientRect().top;
    if (top < rect) tmp += closingtag + opentag;
    top = rect;
    tmp += spans[i].textContent + ' ';
  }
  container.innerHTML = tmp += closingtag;
}

splitLines(document.querySelectorAll('p')[0], '<span>', '</span>')

It works great and accomplishes what I needed, but only selects the first paragraph of the DOM, not the others. It seems like adding forEach method might solve what I'm looking for, but I don't know how to implement it within this code.

Any help would be very appreciated.

Thanks

Barmar
  • 741,623
  • 53
  • 500
  • 612
  • 4
    what do you think does the `[0]` after your `querySelectorAll()` call? – Thomas May 14 '21 at 00:41
  • You shouldn't assign the opening and closing tags separately to `innerHTML`. After you assign to `innerHTML`, it reparses it completely, and will close all the tags. You should process all the HTML as a string, then assign it to `innerHTML` at once at the end. – Barmar May 14 '21 at 00:47
  • 1
    It's also dangerous to rewrite the HTML of lots of random elements. You'll lose any dynamic DOM properties in those elements, such as event listeners. – Barmar May 14 '21 at 00:47

1 Answers1

1

You would want something like:

document.querySelectorAll('p').forEach(p => splitLines(p, '<span>','</span>'))
charlietfl
  • 170,828
  • 13
  • 121
  • 150