Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jquery - Truncate Text by Line (not by character count)

I need a Jquery script to truncate a text paragraph by line (not by character count).

I would like to achieve an evenly truncated text-block. It should have a "more" and "less" link to expand and shorten the text paragraph. My text paragraph is wrapped in a div with a class, like this:

<div class="content">
<h2>Headline</h2>
<p>The paragraph Text here</p>
</div>

The closest solution i could find on SOF is the one below (but it`s for textarea element and does not work for me): Limiting number of lines in textarea

Many thanks for any tips. Ben

like image 517
Bento Graphic Avatar asked Jun 28 '10 07:06

Bento Graphic


People also ask

How do you shorten a long string?

Make a loop at the end of the string After cutting the string at the proper length, take the end of the string and tie a knot at the very end, then fold the string over and tie a loop, about the same size as the original loop (about 2cm in diameter).

How do I truncate a string?

Truncate the string (first argument) if it is longer than the given maximum string length (second argument) and return the truncated string with a ... ending. The inserted three dots at the end should also add to the string length.

How do you shorten text in JavaScript?

Create a function truncate(str, maxlength) that checks the length of the str and, if it exceeds maxlength – replaces the end of str with the ellipsis character "…" , to make its length equal to maxlength . The result of the function should be the truncated (if needed) string.


2 Answers

For a basic approach, you could take a look at the line-height CSS property and use that in your calculations. Bear in mind that this approach will not account for other inline elements that are larger than that height (e.g. images).

If you want something a bit more advanced, you can get the information about each line using getClientRects() function. This function returns a collection of TextRectangle objects with width, height and offset for each one.

See this answer here for an example (albeit an unrelated goal) of how getClientRects() works.


Update, had a bit of time to come back and update this answer with an actual example. It's basic, but you get the idea:

http://jsbin.com/ukaqu3/2

A couple of pointers:

  • The collection returned by getClientRects is static, it won't update automatically if the containing element's dimensions change. My example works around this by capturing the window's resize event.

  • For some strange standards-compliance reason that I'm not understanding, the element you call getClientRects on must be an inline element. In the example I have, I use a container div with the text in another div inside with display: inline.

like image 121
Andy E Avatar answered Oct 17 '22 02:10

Andy E


I made this little jQuery code to allow me truncate text blocks by line (via CSS classes), feel free to use and comment it.

Here is the jsFiddle, which also include truncate functions by char count or word count. You can see that currently, resize the window won't refresh the block display, I'm working on it.

/*
*   Truncate a text bloc after x lines
*   <p class="t_truncate_l_2">Lorem ipsum magna eiusmod sit labore.</p>
*/  
$("*").filter(function () { 
    return /t_truncate_l_/.test($(this).attr('class')); 
}).each(function() {
    var el = $(this);
    var content = el.text();
    var classList = el.attr('class').split(/\s+/);
    $.each(classList, function(index, item){
        if(/^t_truncate_l_/.test(item)) {
            var n = item.substr(13);
            var lineHeight = parseInt(el.css('line-height'));
            if(lineHeight == 1 || el.css('line-height') == 'normal')
                lineHeight = parseInt(el.css('font-size')) * 1.3;
            var maxHeight = n * lineHeight;
            var truncated = $.trim(content);
            var old; 
            if(el.height() > maxHeight)
                truncated += '...';
            while(el.height() > maxHeight && old != truncated) {
                old = truncated;
                truncated = truncated.replace(/\s[^\s]*\.\.\.$/, '...'); 
                el.text(truncated);
            }
        }
    });
});
like image 3
zessx Avatar answered Oct 17 '22 02:10

zessx