Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to dynamically get the last line of a text fitted in a fixed width?

This is an example:

<div class="parent">
  Contrary to popular belief Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old.
</div>

this div is 200px width, and I need to catch the last line I can see in the browser, wrapping it with a span. Such as <span>it over 2000 years old.</span> in my case.

Is this possible with jquery/javascript? Or at least get the lenght of this "last" line.

EDIT: I think I find a good way: https://jsfiddle.net/qqkxyq42/2/

like image 610
markzzz Avatar asked May 09 '16 15:05

markzzz


2 Answers

This is probably a bit more hardcore than you were hoping, however you could check the height of the parent, and start removing word by word, checking it every iteration, until the height changes. Then you'll know at what word or symbol the last line begins.

var words = text.split(' '); // An array of all the words split by spaces, since that's where text breaks by default.
var lastLine = []; // Put all words that don't change the height here.
var currentHeight = parentEl.clientHeight; // The starting height.

while(words[0]){
  parentEl.innerText = words.join(' ');
  if (parentEl.clientHeight < currentHeight) {
    var span = document.createElement('span');
    span.innerText = lastLine.join(' ');
    parentEl.appendChild(span);
    break;
  }

  lastLine.shift(words.pop);
}

I'm assuming you're doing this to style the text in some way, currently there is a pseudo-selector called first-line, which targets the first line of text on the selector, however we've yet to see a last-line or nth-line(#) selectors, which is a shame, as it seems like a pretty reasonable thing to have.

like image 105
GMchris Avatar answered Sep 21 '22 10:09

GMchris


This works. Goes word by word calculating the width

https://jsfiddle.net/stevenkaspar/ht7ostyx/9/

<div

 class="parent" id='text'>
  Contrary to popular belief Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old.
</div>

<script>

function getWidth(pre_space, str, post_space, append_elem){
  var pre = (pre_space) ? '&nbsp;' : '';
  var post = (post_space) ? '&nbsp;' : '';

  var tmp_div = $('<span style="white-space: nowrap;">'+pre+str+post+'</span>');
  append_elem.append(tmp_div);
  var width =  tmp_div.width();
  tmp_div.remove();
  return width;
}
function linkEndLine(elem_id){
  var elem = document.getElementById(elem_id);
  var width = $(elem).width();
  var text = elem.innerText;
  var words = text.split(' ');
  var line_width = 0;
  var current_line = '';
  var lines = [];
  words.map(function(word, index){

    if(line_width == 0){
      line_width += getWidth(false, word, false, $(elem));
    }
    else {
      line_width += getWidth(true, word, false, $(elem));
    }

    if( (line_width / width) > 1){
      lines.push(current_line);

      line_width = getWidth(false, word, false, $(elem)); // new line
      current_line = '';
    }
    current_line += ((current_line != '') ? ' ' : '') + word;

    if(index == (words.length-1)){
      lines.push(current_line);
    }
  })
  var end_index = lines.length - 1;
  lines[end_index] = '<a href="#">'+lines[end_index]+'</a>';
  elem.innerHTML = lines.join(' ');
}
linkEndLine('text');

</script>
like image 39
Steven Kaspar Avatar answered Sep 21 '22 10:09

Steven Kaspar