2
\$\begingroup\$

I am making a text snipper plugin for WordPress. Basically, I want it to truncate multiline text that overflows the height of its container and add "...". My code works for direct child elements, too. It is also responsive and keeps working based on window resize.

However, I'm worried that my method might be too much of a resource hog. To snip the text, I continuously set the text equal to itself - 1 character until the overflow stops. Is this an efficient way of doing this?

snipClass is a variable passed from the WordPress plugin. It's just an HTML class to run Text Snipper on. I notice that, especially on window resize, the response is kind of sluggish, but I'm not sure how else I could pull this off. I suppose doing intervals of three characters to snip instead of 1 would lighten the task load, but I want this to be as precise as possible.

(function($) {

    function trimText (el, wrapper) {
        //If there is text in this element, and there is still overflow, trim this element's text
        if ( el.text() != "" && wrapper.clientHeight < wrapper.scrollHeight ) {
            el.text( function (key, string) {
                return string.substring(0, string.length - 1);
            });

            trimText(el, wrapper);
        } else {
            return false;
        }   
    }

    function prepareSnipText (first, originalText) {

            $('.' + snipClass).each( function (key) {

                if (first) {
                    originalText.push($(this).html());
                } else {
                    $(this).html(originalText[key]);
                }
                var wrapper = this;

                //Trim text
                if ( wrapper.clientHeight < wrapper.scrollHeight) {
                    //Handle child elements
                    if ($(this).children().length > 0) { 
                        $(this).children().reverse().each( function () {
                            trimText($(this), wrapper);
                         }); 
                    //Handle elements with no children
                    } else { 
                        trimText($(this), wrapper);
                    }
                } 
                //Add '...'
                if ($(this).children().length > 0) { 
                    $(this).children().reverse().each( function () {
                        var isNotEmpty = checkEmpty($(this));
                        if (isNotEmpty) {
                            $(this).text($(this).text().substring(0, $(this).text().length - 3) + '...');
                            return false;
                        }
                     });
                } else {
                    $(this).text($(this).text().substring(0, $(this).text().length - 3) + '...');
                }

        }); 
    }

    function checkEmpty (el) {
        if (el.text() != "") { return true; } else { return false; }
    }

    //http://www.mail-archive.com/discuss@jquery.com/msg04261.html
    jQuery.fn.reverse = [].reverse;

    $(document).ready( function() {

        if (  $('.' + snipClass).length > 0 ) {

            var originalText = [];

            prepareSnipText(true, originalText);

            // Responsive - trim text again for smaller window, or readd HTML for larger, then snip again
            $(window).resize( function () {
                prepareSnipText(false, originalText);
            });

        }
    });

}(jQuery));
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.