I am working on creating a WordPress plugin to snip overflowing multiline text and add "...". It's pretty basic for now, but I am using some for loops and am just wondering if this is the most efficient way to go about doing this without clogging resources.
(function($) {
//Praveen Prasad "HasScrollBar" function adapted http://stackoverflow.com/questions/7341865/checking-if-jquery-is-loaded-using-javascript
$.fn.hasOverflow = function() {
var elm = $(this);
var hasOverflow = false;
if ( elm.clientHeight < elm.scrollHeight ) {
hasOverflow = true;
}
return hasOverflow;
}
//http://www.mail-archive.com/discuss@jquery.com/msg04261.html
jQuery.fn.reverse = [].reverse;
$(document).ready( function() {
if ( $('.' + snipClass).length > 0 ) {
var count = 0;
for (var i = 0; i < 10000; i++) {
$('.' + snipClass).each( function () {
var el = this;
//Check for overflows
if ( el.clientHeight < el.scrollHeight) {
if ($(this).children().length > 0) { //Handle child elements
$("> *", this).reverse().each( function () {
for (var j = 0; j < 10000; j++) {
if ( $(this).text() != "" && el.clientHeight < el.scrollHeight ) {
$(this).text($(this).text().substring(0,$(this).text().length - 1));
} else {
break;
}
}
});
} else { //Handle elements with no children
$(this).text($(this).text().substring(0,$(this).text().length - 1));
}
} else { //Add '...'
count++;
}
});
//Add ... once finished
if ( count >= $('.' + snipClass).length) {
$('.' + snipClass).each( function () {
var el = this;
if ($(this).children().length > 0) { //Handle child elements
$("> *", this).reverse().each( function () {
if ( $(this).text() != "" ) {
$(this).text($(this).text().substring(0, $(this).text().length - 3) + "...");
}
});
} else { //Handle elements with no children
$(this).text($(this).text().substring(0, $(this).text().length - 3) + "...");
}
});
break;
}
}
}
});
}(jQuery));
Brief explanation: "snipClass" is the value from the textfield in the plugin's settings page. If the element in question has a wrapper that is say 200px, but its text overflows it, I keep trimming text letter by letter until it doesn't overflow anymore. I opted to go with for loops rather than intervals, because even with 1s intervals, you could see the text getting removed letter by letter, and it's much faster with the for loop. If the wrapper has any direct children (maybe a tag with
elements), my plugin goes in reverse order to snip text from them until there is no overflow.