Reputation: 791
I have the following requirement for a component:
Given a container that contains some html/text, if the content reaches a specified height (example: 175px) the following needs to happen:
And it needs to run in all browsers (including IE)
I've tried a number of libraries:
readmore.js (http://jedfoster.com/Readmore.js/) - This one gets me close, but the "more" link is appended as an extra div after the main content div and not at the end of the breakpoint of the text.
clamp.js (https://github.com/josephschmitt/Clamp.js/) - This adds the "..." at a specified height but doesn't add a clickable more link that can expand and has problems running in IE
dotdotdot jQuery plugin - Same problem as Clamp
What are my options for doing something like this? Is there any way to avoid font/pixel math?
Upvotes: 3
Views: 1192
Reputation: 159
I created a working solution for what you are trying to accomplish. Check out my fiddle here: https://jsfiddle.net/akm1essL/5/.
JS
var container = document.getElementById('container');
var myText = container.getElementsByClassName('text-content')[0];
var spanEl = myText.childNodes[0];
var originalStr = myText.textContent.toString();
var truncatedStr;
// create the "More button" to be appended
var moreButton = document.createElement('span');
moreButton.setAttribute('class', 'readMore');
moreButton.setAttribute('id', 'moreButton');
checkHeight();
function checkHeight() {
var maxHeight = 170;
if (myText.clientHeight > maxHeight) {
truncate();
}
}
function truncate() {
var str, hasButton;
if (!hasButton) {
myText.appendChild(moreButton);
setButton("more");
hasButton = true;
}
str = myText.textContent;
truncatedStr = str.slice(0, str.lastIndexOf(' '));
spanEl.textContent = truncatedStr;
checkHeight(myText.clientHeight);
}
function showFull() {
spanEl.textContent = originalStr;
setButton();
}
function showTruncated() {
spanEl.textContent = truncatedStr;
setButton("more");
}
function setButton(display) {
var btn = document.getElementById("moreButton");
if (display === "more") {
btn.textContent = "...More";
btn.addEventListener("click", showFull);
btn.removeEventListener("click", showTruncated);
} else {
btn.textContent = "...Less";
btn.removeEventListener("click", showFull);
btn.addEventListener("click", showTruncated);
hasButton = false;
}
}
To shorten the text, this solution checks the content height initially, then runs the truncate() function and shortens the text one word at a time from the end until it fits within the maximum height. If the text you have to shorten ends up being 10,000 words long, this will not be the best approach, but I am not sure of your use case.
HTML
<div id="container">
<p class="text-content">
<span>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Nam suscipit, labore nemo distinctio incidunt laboriosam, est inventore totam voluptatem explicabo unde eius et. Provident harum, dolor tempora, aut consectetur excepturi. Dolorem aperiam distinctio ratione quam saepe eius ex, quasi, corporis molestias at laborum commodi, quis voluptatum possimus temporibus. Earum quis, et laudantium labore maxime fuga numquam explicabo!</span>
</p>
</div>
Also I tested it in IE9, 10, Chrome, and FF and it works for all.
Upvotes: 2