2
\$\begingroup\$

I have written a JavaScript that can read every defined html element and changes the color for each char inside the selected element.
It works fine for smaller projects / sites, however will be laggy and even crash the browser if there are too many elements to process. Appart from 'Use JQuery', what could I do to improve the Performance? I know that .fontcolor() is deprecated. Alternatives are welcome.

/**
 * Defines all possible colors for the chars.
 * 
 * @type {string[]} Array of strings with Hex Color values.
 */
var colors = [ "#1C1C1C", "#BDBDBD", "#FA58AC", "#FA58F4", "#AC58FA",
        "#5858FA", "#58ACFA", "#58FAF4", "#58FAAC", "#58FA58", "#ACFA58",
        "#F4FA58", "#FAAC58", "#FA5858" ];

/**
 * Define all elements that can have the text replaced.
 * 
 * @type {NodeList}
 */
var ps = document.getElementsByTagName("p");
var h1s = document.getElementsByTagName("h1");
var h2s = document.getElementsByTagName("h2");
var h3s = document.getElementsByTagName("h3");

/**
 * Wrap all elements inside one parent
 * 
 * @type {*[]} Array of Array<Elements>
 */
var allDomElements = [ ps, h1s, h2s, h3s ];

/**
 * Starts the party mode
 * 
 * @param count
 *            loop gets interrupted after 20 times.
 */
function party(count) {
    // For each array in wrapper
    for (var e = 0; e < allDomElements.length; e++) {
        // For each element in array
        for (var d = 0; d < allDomElements[e].length; d++) {
            // Reference to the current element
            var currentElement = allDomElements[e][d];
            // Gets the text value of the element
            var text = currentElement.innerText;
            var result = "";

            // For each char in text change the color of a single char
            for (var i = 0, len = text.length; i < len; i++) {
                var char = text.charAt(i);
                result += setRandomColorForChar(char);
            }

            // Sets the HTML of the element to be the result
            currentElement.innerHTML = result;
        }
    }
    // If the function hasn't been called 5x times, wait 5 seconds and
    // repeat
    count = count + 1;
    if (!(count > 5)) {
        window.setTimeout(function() {
            party(count);
        }, 5000);
    } else {
        stopParty();
    }
}

/**
 * Function randomly colorizes as single char.
 * 
 * @param char
 *            Char to be colorized
 * @returns {string} Colorized char
 */
function setRandomColorForChar(char) {
    var random = getRandomColor();
    var color = colors[random];
    return char.fontcolor(color);
}

/**
 * Returns a random number in the range of colors.length
 * 
 * @returns {number} A random number
 */
function getRandomColor() {
    return Math.floor((Math.random() * colors.length) + 0);
}

function stopParty() {
    // For each array in wrapper
    for (var e = 0; e < allDomElements.length; e++) {
        // For each element in array
        for (var d = 0; d < allDomElements[e].length; d++) {
            // Reference to the current element
            var currentElement = allDomElements[e][d];
            // Gets the text value of the element
            var html = currentElement.innerText;
            var clean = html.replace(/<font.*?>/, '');
            clean = clean.replace(/<\/font>/, '');
            currentElement.innerHTML = clean;
        }
    }
}

JS Fiddle

\$\endgroup\$
3
  • 2
    \$\begingroup\$ You are causing too much layout trashing reading innerHtml and then changing it, you should batch all read operations first and then all write ones \$\endgroup\$
    – juvian
    Commented Oct 27, 2016 at 14:46
  • \$\begingroup\$ @juvian Please write that as an answer. \$\endgroup\$ Commented Oct 27, 2016 at 17:01
  • \$\begingroup\$ @200_success Do you have an example of taking too long? Have checked and it does not seem to cause layout trashing. Another thing you could try would be to only apply that to elements in current view, but would need a better example to see if what is causing your bottlenet is the js or the painting \$\endgroup\$
    – juvian
    Commented Oct 27, 2016 at 17:31

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.