I've been trying to figure out how to do this (if it's even possible) and have drawn a blank...
I have some text that will wrap onto multiple lines. I want to detect each individual line, and wrap it in a span. Finally, I want to assign a class to each span from a looping array.
For example...!
<div id="quote">
I have some text that
wraps onto three lines
in this container
</div>
I want to get my jQuery to parse those lines, detect where it wraps, and turn it into this:
<div id="quote">
<span class="red-bg">I have some text that</span>
<span class="orange-bg">wraps onto three lines</span>
<span class="yellow-bg">in this container</span>
</div>
The reason that I want to do this dynamically is that I'm doing it within responsive templates, so sometimes the same text will only wrap onto two lines, or maybe four in an iPhone.
Is this doable? I've found this -> http://vidasp.net/tinydemos/numberOfLines.html which calculates the number of lines used in a block of text, but that doesn't really extend to do what I need.
Use the textContent property to get the text of a span element, e.g. const text = span. textContent . The textContent property will return the text content of the span and its descendants.
The Multiline Text Field can be used to store larger amounts of text. The Multiline Text Field offers a lot of formatting options, such as: Adding bulleted and numbered lists. Use bold, italics and underline styling.
It seems like you're asking how to split the text where it is naturally wrapped by the browser. Unfortunately, this isn't straightforward at all. Neither is it robust — consider the following scenario:
The result is that the spans no longer correlate to where the lines start and finish. Of course, this scenario is avoidable using fixed-width elements or you can rejig the whole thing when the browser resizes, but that's just an example of how it can break.
Still, it's not easy. A similar question has come up before (albeit, with a different goal) and two solutions appeared, which could both be of help here:
Don't actually wrap the text in spans, but get the position and dimensions of each line of text using getClientRects()
. Then, create the number of spans necessary and position/resize them behind each line of text.
Pros
Cons
The demo provided with the answer shows how you can highlight the line of text currently beneath the mouse.
Split the text into an array using the split() method with a word boundary or white-space as the argument passed. Rejoin the array into a string with </span><span>
between each element and wrap the whole thing with <span>
and </span>
, and replace the original text node with the resulting HTML in the containing element. Now, iterate over each of those span elements checking its y position within the container. When the y position increases, you know that you've reached a new line and the previous elements can be merged into a single span.
Pros
Cons
There may be other ways to achieve your goal, but I'm not sure of any myself. TextNode.splitText(n)
can split a TextNode in twain (!) when passed a numeric index of the character you want to split on. Neither of the above solutions are perfect, and both break as soon as the containing element resizes.
I put together a fiddle implementing solution #2 by Andy E (above). I.e. Split, join, loop, merge
Here's the algorithm:
var spanInserted = $('#someText').html().split(" ").join(" </span><span>");
var wrapped = ("<span>").concat(spanInserted, "</span>");
$('#someText').html(wrapped);
var refPos = $('#someText span:first-child').position().top;
var newPos;
$('#someText span').each(function(index) {
newPos = $(this).position().top
if (index == 0){
return;
}
if (newPos == refPos){
$(this).prepend($(this).prev().text() + " ");
$(this).prev().remove();
}
refPos = newPos;
});
Enjoy...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With