
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);






