Smooth Slide Toggle In Vanilla JavaScript

Category: Animation , Javascript | October 23, 2017
Author: Michal Niewitala
Views Total: 3,752 views
Official Page: Go to website
Last Update: October 23, 2017
License: MIT

Preview:

Smooth Slide Toggle In Vanilla JavaScript

Description:

A vanilla JavaScript version of jQuery’s .slideToggle() function that enables you implement the smooth (60 FPS) slide down and slide up effect on matched elements.

How to use it:

Create a toggle button to toggle the element with a sliding motion.

<button>Toggle</button>
<ul class="block">
  <li>Element 1</li>
  <li>Element 2</li>
  <li>Element 3</li>
  <li>Element 4</li>
  <li>Element 5</li>
  ...
</ul>

The main JavaScript.

(function() {
  var block, i, j, len, len1, ref, ref1, slideToggler, trigger,
    bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
    indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };

  slideToggler = (function() {
    function slideToggler(el1) {
      this.el = el1;
      this.toggle = bind(this.toggle, this);
      if (!this.el) {
        return;
      }
      this.height = this.getHeight();
    }

    slideToggler.prototype.getHeight = function() {
      var clone;
      if (this.el.clientHeight > 10) {
        return this.el.clientHeight;
      }
      clone = this.el.cloneNode(true);
      clone.style.cssText = 'position: absolute; visibility: hidden; display: block;';
      this.el.parentNode.appendChild(clone);
      this.height = clone.clientHeight;
      this.el.parentNode.removeChild(clone);
      return this.height;
    };

    slideToggler.prototype.toggle = function(time) {
      var currHeight, disp, el, end, init, ref, repeat, start;
      if (!(this.height > 0)) {
        this.height = this.getHeight();
      }
      if (time == null) {
        time = this.height;
      }
      currHeight = this.el.clientHeight * (getComputedStyle(this.el).display !== 'none');
      ref = currHeight > this.height / 2 ? [this.height, 0] : [0, this.height], start = ref[0], end = ref[1];
      disp = end - start;
      el = this.el;
      this.el.classList[end === 0 ? 'remove' : 'add']('open');
      this.el.style.cssText = "overflow: hidden; display: block; padding-top: 0; padding-bottom: 0";
      init = (new Date).getTime();
      repeat = function() {
        var i, instance, ref1, repeatLoop, results, step;
        instance = (new Date).getTime() - init;
        step = start + disp * instance / time;
        if (instance <= time) {
          el.style.height = step + 'px';
        } else {
          el.style.cssText = "display: " + (end === 0 ? 'none' : 'block');
        }
        repeatLoop = requestAnimationFrame(repeat);
        if (ref1 = Math.floor(step), indexOf.call((function() {
          results = [];
          for (var i = start; start <= end ? i <= end : i >= end; start <= end ? i++ : i--){ results.push(i); }
          return results;
        }).apply(this), ref1) < 0) {
          return cancelAnimationFrame(repeatLoop);
        }
      };
      return repeat();
    };

    return slideToggler;

  })();

  ref = document.querySelectorAll('.block');
  for (i = 0, len = ref.length; i < len; i++) {
    block = ref[i];
    block.toggler = new slideToggler(block);
  }

  ref1 = document.querySelectorAll('button');
  for (j = 0, len1 = ref1.length; j < len1; j++) {
    trigger = ref1[j];
    trigger.addEventListener('click', function() {
      var ref2;
      return (ref2 = this.parentNode.querySelector('.block').toggler) != null ? ref2.toggle() : void 0;
    });
  }

}).call(this);

You Might Be Interested In:


Leave a Reply