Pure JavaScript effects

I often use slideUp, slideDown, slideToggle, fadeIn, fadeOut and fadeToggle as effects in my projects. I have been using JQuery a lot but want to reduce my dependency on that framework and do everything in VanillaJS.

I was first thinking that I should add effects to the HTMLElement interface ( HTMLElement.prototype.FUNCTIONNAME) but read that it wasn’t a good idea.

This plugin has been tested and is working with Google Chrome (75.0.3770.100), Mozilla Firefox (67.0.4), Microsoft Edge (42.17134.1.0) and Internet Explorer (11.829.17134.0), without any polyfill. If you want to support older browsers, check out our post on transpilation and polyfilling of JavaScript.

JavaScript

I have created a JavaScript plugin with functions inside a namespace to make sure that function names not collide with names in other JavaScript libraries.

var annytab = {};
annytab.effects = (function () {

    'use_strict';

    // Public methods
    return {

        slideDown: function (el, duration, display) {

            // Return if the element is visible
            if (this.isVisible(el) === true) {
                return;
            }

            // Set default values for parameters
            duration = duration || 400;
            display = display || 'block';

            // Display the element
            el.style.display = display;

            // Create variables
            var counter = 0;
            var height = el.offsetHeight;
            var adder = height / (duration / 10);

            // Set height and hide overflow
            el.style.height = '0px';
            el.style.overflow = 'hidden';

            // Increase the height of the element every 10 ms
            var interval = setInterval(function () {
                counter += adder;
                if (counter < height) {
                    // Set element height
                    el.style.height = counter + 'px';
                }
                else {
                    // Reset the element and clear the interval
                    el.style.height = '';
                    el.style.overflow = '';
                    clearInterval(interval);
                }

            }, 10);

            // Return the element
            return el;
        },
        slideUp: function (el, duration) {

            // Return if the element not is visible
            if (this.isVisible(el) === false) {
                return;
            }

            // Set default values for parameters
            duration = duration || 400;

            // Create variables
            var height = el.offsetHeight;
            var counter = height;
            var subtractor = height / (duration / 10);

            // Hide overflow
            el.style.overflow = 'hidden';

            // Decrease the height of the element every 10 ms
            var interval = setInterval(function () {
                counter -= subtractor;
                if (counter > 0) {
                    // Set element height
                    el.style.height = counter + 'px';
                }
                else {
                    // Reset the element and clear the interval
                    el.style.display = 'none';
                    el.style.overflow = '';
                    el.style.height = '';
                    clearInterval(interval);
                }

            }, 10);

            // Return the element
            return el;
        },
        slideToggle: function (el, duration, display) {

            // Set default values for parameters
            duration = duration || 400;
            display = display || 'block';

            // Check if we should slide up or slide down
            if (this.isVisible(el) === true) {
                this.slideUp(el, duration);
            }
            else {
                this.slideDown(el, duration, display);
            }

            // Return the element
            return el;
        },
        fadeIn: function (el, duration, display) {

            // Return if the element is visible
            if (this.isVisible(el) === true) {
                return;
            }

            // Set default values for parameters
            duration = duration || 400;
            display = display || 'block';

            // Display the element
            el.style.display = display;

            // Create variables
            var counter = 0;
            var adder = 100 / (duration / 10);

            // Set opacity
            el.style.opacity = 0.00;
            el.style.filter = 'alpha(opacity=0)'; /* For IE8 and earlier */

            // Increase the opacity of the element every 10 ms
            var interval = setInterval(function () {
                counter += adder;
                if (counter < 100) {
                    // Set element opacity
                    el.style.opacity = counter / 100;
                    el.style.filter = 'alpha(opacity=' + counter + ')'; /* For IE8 and earlier */
                }
                else {
                    // Reset the element and clear the interval
                    el.style.opacity = '';
                    el.style.filter = ''; /* For IE8 and earlier */
                    clearInterval(interval);
                }

            }, 10);

            // Return the element
            return el;
        },
        fadeOut: function (el, duration) {

            // Return if the element not is visible
            if (this.isVisible(el) === false) {
                return;
            }

            // Set default values for parameters
            duration = duration || 400;

            // Create variables
            var counter = 100;
            var subtractor = 100 / (duration / 10);

            // Set opacity
            el.style.opacity = 1.00;
            el.style.filter = 'alpha(opacity=100)'; /* For IE8 and earlier */

            // Decrease the height of the element every 10 ms
            var interval = setInterval(function () {
                counter -= subtractor;
                if (counter > 0) {
                    el.style.opacity = counter / 100;
                    el.style.filter = 'alpha(opacity=' + counter + ')'; /* For IE8 and earlier */
                }
                else {
                    // Reset the element and clear the interval
                    el.style.display = 'none';
                    el.style.opacity = '';
                    el.style.filter = ''; /* For IE8 and earlier */
                    clearInterval(interval);
                }

            }, 10);

            // Return the element
            return el;
        },
        fadeToggle: function (el, duration, display) {

            // Set default values for parameters
            duration = duration || 400;
            display = display || 'block';

            // Check if we should fade out or fade in
            if (this.isVisible(el) === true) {
                this.fadeOut(el, duration);
            }
            else {
                this.fadeIn(el, duration, display);
            }

            // Return the element
            return el;
        },
        isVisible: function (el) {
            if (typeof el === 'undefined' || el === null) { return false; }
            return !!(el.offsetWidth || el.offsetHeight || el.getClientRects().length);
        }
    };

})();

How to use the plugin

To apply an effect to many elements, use a loop. You need to add the element as a parameter to a function, other parameters have default values.

function toggleForm()
{
    // Get the container
    var container = document.getElementById('inputForm');

    // Check if it is visible
    var visible = annytab.effects.isVisible(container);

    // Hide all containers
    var collection = document.getElementsByClassName('hideable');
    for (var i = 0; i < collection.length; i++) {
        annytab.effects.slideUp(collection[i], 500);
    }

    // Show the container if it wasn't visible
    if (visible === false) {
        annytab.effects.slideDown(container, 500);
    }

} // End of the toggleForm method

Leave a Reply

Your email address will not be published. Required fields are marked *