/** * uiMorphingButton_inflow.js v1.0.0 * http://www.codrops.com * * Licensed under the MIT license. * http://www.opensource.org/licenses/mit-license.php * * Copyright 2014, Codrops * http://www.codrops.com */ ;( function( window ) { 'use strict'; var transEndEventNames = { 'WebkitTransition': 'webkitTransitionEnd', 'MozTransition': 'transitionend', 'OTransition': 'oTransitionEnd', 'msTransition': 'MSTransitionEnd', 'transition': 'transitionend' }, transEndEventName = transEndEventNames[ Modernizr.prefixed( 'transition' ) ], support = { transitions : Modernizr.csstransitions }; function extend( a, b ) { for( var key in b ) { if( b.hasOwnProperty( key ) ) { a[key] = b[key]; } } return a; } function UIMorphingButtonInflow( el, options ) { this.el = el; this.options = extend( {}, this.options ); extend( this.options, options ); this._init(); } UIMorphingButtonInflow.prototype.options = { closeEl : '', onBeforeOpen : function() { return false; }, onAfterOpen : function() { return false; }, onBeforeClose : function() { return false; }, onAfterClose : function() { return false; } } UIMorphingButtonInflow.prototype._init = function() { // save element height this.elH = this.el.offsetHeight; // the button this.button = this.el.querySelector( 'button' ); // state this.expanded = false; // content el this.contentEl = this.el.querySelector( '.morph-content' ); // init events this._initEvents(); } UIMorphingButtonInflow.prototype._initEvents = function() { var self = this; // open this.button.addEventListener( 'click', function() { self.toggle(); } ); // close if( this.options.closeEl !== '' ) { var closeEl = this.el.querySelector( this.options.closeEl ); if( closeEl ) { closeEl.addEventListener( 'click', function() { self.toggle(); } ); } } } UIMorphingButtonInflow.prototype.toggle = function() { if( this.isAnimating ) return false; // callback if( this.expanded ) { this.options.onBeforeClose(); } else { // add class active (solves z-index problem when more than one button is in the page) classie.addClass( this.el, 'active' ); this.options.onBeforeOpen(); } this.isAnimating = true; var self = this, onEndTransitionFn = function( ev ) { if( ev.target !== this ) return false; if( support.transitions ) { this.removeEventListener( transEndEventName, onEndTransitionFn ); } self.isAnimating = false; // callback if( self.expanded ) { // remove class active (after closing) classie.removeClass( self.el, 'active' ); self.options.onAfterClose(); } else { self.options.onAfterOpen(); } self.expanded = !self.expanded; }; if( support.transitions ) { this.el.addEventListener( transEndEventName, onEndTransitionFn ); } else { onEndTransitionFn(); } // add/remove class "open" to the button wraper this.el.style.height = this.expanded ? this.elH + 'px' : this.contentEl.offsetHeight + 'px'; if( this.expanded ) { classie.removeClass( this.el, 'open' ); } else { classie.addClass( this.el, 'open' ); } } // add to global namespace window.UIMorphingButtonInflow = UIMorphingButtonInflow; })( window );