Reputation: 7768
I have a <div>
element and which will show a paragraph with no line breaks like in the example
<div>
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum
</div>
Here the text will split as a number of lines according to the width of its container, I am trying to wrap each of the auto-sized lines into a span element.but I failed to do this because we can't find the end of the lines using \n
.is there any method to achieve this?
Note- I find an answer for this when i am searching Can I wrap each line of multi-line text in a span? . but the questin is not similer to this,here i have a test in single line and there is no line break.but the above question have line break on each line
Upvotes: 3
Views: 5213
Reputation: 222
To be able to calculate when there is a new line, we must first know when the last word of the sentence is. To find out, we will put a tag for every word. We then take the Y coordinates of each word. If there is a difference, we know that a new rule has started.
For updates https://github.com/nielsreijnders/textSplitter/blob/master/src/index.ts
// Openingtag & closingtag has to be a string!!
function splitLines(container, openingtag, closingtag) {
// Get the spans in the paragraph
var spans = container.children,
top = 0,
// set tmp as a string
tmp = '';
// Put spans on each word, for now we use the <n> tag because, we want to save 5 bytes:)
container.innerHTML = container.textContent.replace(/\S+/g, '<n>$&</n>');
// Loop through each words (spans)
for (let i = 0; i < spans.length; i++) {
// Get the height of each word
var rect = spans[i].getBoundingClientRect().top;
// If top is different as the last height of the word use a closingtag and use an opentag after that
if (top < rect) tmp += closingtag + openingtag;
top = rect;
// Add the spans + space between each word
tmp += spans[i].textContent + ' ';
}
// Add the lines back to the paragraph
container.innerHTML = tmp += closingtag;
}
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>')
* {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
line-height: 22px;
}
h1 {
letter-spacing: 1px;
border-bottom: 1px solid #eaecef;
padding-bottom: .5em;
}
p {
font-size: 14px;
width: 350px;
}
p span:nth-child(even) {
color: #fff;
background: #000;
}
<h1>TextSplitter ðŸ¥</h1>
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper ultricies nisi. Nam eget dui.</p>
You have to update the lines when resizing your window!
Upvotes: 12
Reputation: 27041
This should do what you want, or close to it.
function trimByPixel(str, width) {
var spn = $('<span style="visibility:hidden"></span>').text(str).appendTo('body');
var txt = str;
while (spn.width() > width) { txt = txt.slice(0, -1); spn.text(txt + "..."); }
return txt;
}
var stri = $(".str").text();
function run(){
var s = trimByPixel(stri, $(".str").width()).trim()
stri = stri.replace(s,"")
$(".result").append("<span>"+s+"</span>");
if(stri.trim().length > 0){
run();
}
}
run();
Demo
function trimByPixel(str, width) {
var spn = $('<span style="visibility:hidden"></span>').text(str).appendTo('body');
var txt = str;
while (spn.width() > width) { txt = txt.slice(0, -1); spn.text(txt + "..."); }
return txt;
}
var stri = $(".str").text();
function run(){
var s = trimByPixel(stri, $(".str").width()).trim()
stri = stri.replace(s,"")
$(".result").append("<span>"+s+"</span>");
if(stri.trim().length > 0){
run();
$(".str").remove(); //remove original
}
}
run();
.str{ width:300px; }
.result span{ display:block }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="str">
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum
</div>
<div class="result"></div>
Upvotes: 3