Home > Software engineering >  Get not overflowing text length dynamically
Get not overflowing text length dynamically

Time:11-08

Is there a way to get the length of visible part of an overflown text (or the size of the overflown part, to calculate the rest, for the case) with css or javascript?

And if so, could it be calculated dynamically (i.e on window resize?)

The idea is to make a read more button wich span button always sticks at the end of the last visible line, it doesn't matter the screen size.

CodePudding user response:

Something like this involves a lot of factors, for instance, your "text" could be a mixture of text and other elements (<b>, <i>, <img>). Assuming it's just straight text, the following works by splitting the string at various halves, with successively smaller halves, to eventually arrive at the text that gives the same height as your source element with hidden overflow.

function getVisibleText(source)
{
    let yardstick = document.createElement(source.nodeName);
    let sourceRectangle = source.getBoundingClientRect();
    let text = source.textContent;
    
    yardstick.style.width = sourceRectangle.width   "px";
    yardstick.style.position = "absolute";
    yardstick.style.top = "-999px";
    yardstick.style.left = "-999px";
    yardstick.textContent = text;
    source.parentNode.appendChild(yardstick);
    
    let size = text.length;
    let difference = size;
    let yardstickRectangle = yardstick.getBoundingClientRect();
    let result = text;
    while((difference > 1 || yardstickRectangle.height > sourceRectangle.height) && size > 0)
    {
        difference = Math.round(difference / 2);
        if(yardstickRectangle.height > sourceRectangle.height)
            size -= difference;
        else
            size  = difference;
        result = text.substring(0, size);
        yardstick.textContent = result;
        yardstickRectangle = yardstick.getBoundingClientRect();
        console.log(difference, result, yardstickRectangle.height, sourceRectangle.height);
    }
    yardstick.parentNode.removeChild(yardstick);
    
    // Trim to the last whole word
    let match = (new RegExp("\\s \\S*?$", "g")).exec(result)[0];
    if(match)
        result = result.substring(0, result.length - match.length);

    return(result);
}
  • Related