// ----------------------------------- // Slidebars // Version 0.10.3 // http://plugins.adchsm.me/slidebars/ // // Written by Adam Smith // http://www.adchsm.me/ // // Released under MIT License // http://plugins.adchsm.me/slidebars/license.txt // // --------------------- // Index of Slidebars.js // // 001 - Default Settings // 002 - Feature Detection // 003 - User Agents // 004 - Setup // 005 - Animation // 006 - Operations // 007 - API // 008 - User Input ;( function ( $ ) { $.slidebars = function ( options ) { // ---------------------- // 001 - Default Settings var settings = $.extend( { siteClose: true, // true or false - Enable closing of Slidebars by clicking on #sb-site. scrollLock: false, // true or false - Prevent scrolling of site when a Slidebar is open. disableOver: false, // integer or false - Hide Slidebars over a specific width. hideControlClasses: false // true or false - Hide controls at same width as disableOver. }, options ); // ----------------------- // 002 - Feature Detection var test = document.createElement( 'div' ).style, // Create element to test on. supportTransition = false, // Variable for testing transitions. supportTransform = false; // variable for testing transforms. // Test for CSS Transitions if ( test.MozTransition === '' || test.WebkitTransition === '' || test.OTransition === '' || test.transition === '' ) supportTransition = true; // Test for CSS Transforms if ( test.MozTransform === '' || test.WebkitTransform === '' || test.OTransform === '' || test.transform === '' ) supportTransform = true; // ----------------- // 003 - User Agents var ua = navigator.userAgent, // Get user agent string. android = false, // Variable for storing android version. iOS = false; // Variable for storing iOS version. if ( /Android/.test( ua ) ) { // Detect Android in user agent string. android = ua.substr( ua.indexOf( 'Android' )+8, 3 ); // Set version of Android. } else if ( /(iPhone|iPod|iPad)/.test( ua ) ) { // Detect iOS in user agent string. iOS = ua.substr( ua.indexOf( 'OS ' )+3, 3 ).replace( '_', '.' ); // Set version of iOS. } if ( android && android < 3 || iOS && iOS < 5 ) $( 'html' ).addClass( 'sb-static' ); // Add helper class for older versions of Android & iOS. // ----------- // 004 - Setup // Site container var $site = $( '#sb-site, .sb-site-container' ); // Cache the selector. // Left Slidebar if ( $( '.sb-left' ).length ) { // Check if the left Slidebar exists. var $left = $( '.sb-left' ), // Cache the selector. leftActive = false; // Used to check whether the left Slidebar is open or closed. } // Right Slidebar if ( $( '.sb-right' ).length ) { // Check if the right Slidebar exists. var $right = $( '.sb-right' ), // Cache the selector. rightActive = false; // Used to check whether the right Slidebar is open or closed. } var init = false, // Initialisation variable. windowWidth = $( window ).width(), // Get width of window. $controls = $( '.sb-toggle-left, .sb-toggle-right, .sb-open-left, .sb-open-right, .sb-close' ), // Cache the control classes. $slide = $( '.sb-slide' ); // Cache users elements to animate. // Initailise Slidebars function initialise () { if ( ! settings.disableOver || ( typeof settings.disableOver === 'number' && settings.disableOver >= windowWidth ) ) { // False or larger than window size. init = true; // true enabled Slidebars to open. $( 'html' ).addClass( 'sb-init' ); // Add helper class. if ( settings.hideControlClasses ) $controls.removeClass( 'sb-hide' ); // Remove class just incase Slidebars was originally disabled. css(); // Set required inline styles. } else if ( typeof settings.disableOver === 'number' && settings.disableOver < windowWidth ) { // Less than window size. init = false; // false stop Slidebars from opening. $( 'html' ).removeClass( 'sb-init' ); // Remove helper class. if ( settings.hideControlClasses ) $controls.addClass( 'sb-hide' ); // Hide controls $site.css( 'minHeight', '' ); // Remove minimum height. if ( leftActive || rightActive ) close(); // Close Slidebars if open. } } initialise(); // Inline CSS function css() { // Site container height. $site.css( 'minHeight', '' ); var siteHeight = parseInt( $site.css( 'height' ), 10 ), htmlHeight = parseInt( $( 'html' ).css( 'height' ), 10 ); if ( siteHeight < htmlHeight ) $site.css( 'minHeight', $( 'html' ).css( 'height' ) ); // Test height for vh support.. // Custom Slidebar widths. if ( $left && $left.hasClass( 'sb-width-custom' ) ) $left.css( 'width', $left.attr( 'data-sb-width' ) ); // Set user custom width. if ( $right && $right.hasClass( 'sb-width-custom' ) ) $right.css( 'width', $right.attr( 'data-sb-width' ) ); // Set user custom width. // Set off-canvas margins for Slidebars with push and overlay animations. if ( $left && ( $left.hasClass( 'sb-style-push' ) || $left.hasClass( 'sb-style-overlay' ) ) ) $left.css( 'marginLeft', '-' + $left.css( 'width' ) ); if ( $right && ( $right.hasClass( 'sb-style-push' ) || $right.hasClass( 'sb-style-overlay' ) ) ) $right.css( 'marginRight', '-' + $right.css( 'width' ) ); // Site scroll locking. if ( settings.scrollLock ) $( 'html' ).addClass( 'sb-scroll-lock' ); } // Resize Functions $( window ).resize( function () { var resizedWindowWidth = $( window ).width(); // Get resized window width. if ( windowWidth !== resizedWindowWidth ) { // Slidebars is running and window was actually resized. windowWidth = resizedWindowWidth; // Set the new window width. initialise(); // Call initalise to see if Slidebars should still be running. if ( leftActive ) open( 'left' ); // If left Slidebar is open, calling open will ensure it is the correct size. if ( rightActive ) open( 'right' ); // If right Slidebar is open, calling open will ensure it is the correct size. } } ); // I may include a height check along side a width check here in future. // --------------- // 005 - Animation var animation; // Animation type. // Set animation type. if ( supportTransition && supportTransform ) { // Browser supports css transitions and transforms. animation = 'translate'; // Translate for browsers that support it. if ( android && android < 4.4 ) animation = 'side'; // Android supports both, but can't translate any fixed positions, so use left instead. } else { animation = 'jQuery'; // Browsers that don't support css transitions and transitions. } // Animate mixin. function animate( object, amount, side ) { // Choose selectors depending on animation style. var selector; if ( object.hasClass( 'sb-style-push' ) ) { selector = $site.add( object ).add( $slide ); // Push - Animate site, Slidebar and user elements. } else if ( object.hasClass( 'sb-style-overlay' ) ) { selector = object; // Overlay - Animate Slidebar only. } else { selector = $site.add( $slide ); // Reveal - Animate site and user elements. } // Apply animation if ( animation === 'translate' ) { if ( amount === '0px' ) { removeAnimation(); } else { selector.css( 'transform', 'translate( ' + amount + ' )' ); // Apply the animation. } } else if ( animation === 'side' ) { if ( amount === '0px' ) { removeAnimation(); } else { if ( amount[0] === '-' ) amount = amount.substr( 1 ); // Remove the '-' from the passed amount for side animations. selector.css( side, '0px' ); // Add a 0 value so css transition works. setTimeout( function () { // Set a timeout to allow the 0 value to be applied above. selector.css( side, amount ); // Apply the animation. }, 1 ); } } else if ( animation === 'jQuery' ) { if ( amount[0] === '-' ) amount = amount.substr( 1 ); // Remove the '-' from the passed amount for jQuery animations. var properties = {}; properties[side] = amount; selector.stop().animate( properties, 400 ); // Stop any current jQuery animation before starting another. } // Remove animation function removeAnimation () { selector.removeAttr( 'style' ); css(); } } // ---------------- // 006 - Operations // Open a Slidebar function open( side ) { // Check to see if opposite Slidebar is open. if ( side === 'left' && $left && rightActive || side === 'right' && $right && leftActive ) { // It's open, close it, then continue. close(); setTimeout( proceed, 400 ); } else { // Its not open, continue. proceed(); } // Open function proceed() { if ( init && side === 'left' && $left ) { // Slidebars is initiated, left is in use and called to open. $( 'html' ).addClass( 'sb-active sb-active-left' ); // Add active classes. $left.addClass( 'sb-active' ); animate( $left, $left.css( 'width' ), 'left' ); // Animation setTimeout( function () { leftActive = true; }, 400 ); // Set active variables. } else if ( init && side === 'right' && $right ) { // Slidebars is initiated, right is in use and called to open. $( 'html' ).addClass( 'sb-active sb-active-right' ); // Add active classes. $right.addClass( 'sb-active' ); animate( $right, '-' + $right.css( 'width' ), 'right' ); // Animation setTimeout( function () { rightActive = true; }, 400 ); // Set active variables. } } } // Close either Slidebar function close( url, target ) { if ( leftActive || rightActive ) { // If a Slidebar is open. if ( leftActive ) { animate( $left, '0px', 'left' ); // Animation leftActive = false; } if ( rightActive ) { animate( $right, '0px', 'right' ); // Animation rightActive = false; } setTimeout( function () { // Wait for closing animation to finish. $( 'html' ).removeClass( 'sb-active sb-active-left sb-active-right' ); // Remove active classes. if ( $left ) $left.removeClass( 'sb-active' ); if ( $right ) $right.removeClass( 'sb-active' ); if ( typeof url !== 'undefined' ) { // If a link has been passed to the function, go to it. if ( typeof target === undefined ) target = '_self'; // Set to _self if undefined. window.open( url, target ); // Open the url. } }, 400 ); } } // Toggle either Slidebar function toggle( side ) { if ( side === 'left' && $left ) { // If left Slidebar is called and in use. if ( ! leftActive ) { open( 'left' ); // Slidebar is closed, open it. } else { close(); // Slidebar is open, close it. } } if ( side === 'right' && $right ) { // If right Slidebar is called and in use. if ( ! rightActive ) { open( 'right' ); // Slidebar is closed, open it. } else { close(); // Slidebar is open, close it. } } } // --------- // 007 - API this.slidebars = { open: open, // Maps user variable name to the open method. close: close, // Maps user variable name to the close method. toggle: toggle, // Maps user variable name to the toggle method. init: function () { // Returns true or false whether Slidebars are running or not. return init; // Returns true or false whether Slidebars are running. }, active: function ( side ) { // Returns true or false whether Slidebar is open or closed. if ( side === 'left' && $left ) return leftActive; if ( side === 'right' && $right ) return rightActive; }, destroy: function ( side ) { // Removes the Slidebar from the DOM. if ( side === 'left' && $left ) { if ( leftActive ) close(); // Close if its open. setTimeout( function () { $left.remove(); // Remove it. $left = false; // Set variable to false so it cannot be opened again. }, 400 ); } if ( side === 'right' && $right) { if ( rightActive ) close(); // Close if its open. setTimeout( function () { $right.remove(); // Remove it. $right = false; // Set variable to false so it cannot be opened again. }, 400 ); } } }; // ---------------- // 008 - User Input function eventHandler( event, selector ) { event.stopPropagation(); // Stop event bubbling. event.preventDefault(); // Prevent default behaviour. if ( event.type === 'touchend' ) selector.off( 'click' ); // If event type was touch, turn off clicks to prevent phantom clicks. } // Toggle left Slidebar $( '.sb-toggle-left' ).on( 'touchend click', function ( event ) { eventHandler( event, $( this ) ); // Handle the event. toggle( 'left' ); // Toggle the left Slidbar. } ); // Toggle right Slidebar $( '.sb-toggle-right' ).on( 'touchend click', function ( event ) { eventHandler( event, $( this ) ); // Handle the event. toggle( 'right' ); // Toggle the right Slidbar. } ); // Open left Slidebar $( '.sb-open-left' ).on( 'touchend click', function ( event ) { eventHandler( event, $( this ) ); // Handle the event. open( 'left' ); // Open the left Slidebar. } ); // Open right Slidebar $( '.sb-open-right' ).on( 'touchend click', function ( event ) { eventHandler( event, $( this ) ); // Handle the event. open( 'right' ); // Open the right Slidebar. } ); // Close Slidebar $( '.sb-close' ).on( 'touchend click', function ( event ) { if ( $( this ).is( 'a' ) || $( this ).children().is( 'a' ) ) { // Is a link or contains a link. if ( event.type === 'click' ) { // Make sure the user wanted to follow the link. event.stopPropagation(); // Stop events propagating event.preventDefault(); // Stop default behaviour var link = ( $( this ).is( 'a' ) ? $( this ) : $( this ).find( 'a' ) ), // Get the link selector. url = link.attr( 'href' ), // Get the link url. target = ( link.attr( 'target' ) ? link.attr( 'target' ) : '_self' ); // Set target, default to _self if not provided close( url, target ); // Close Slidebar and pass link target. } } else { // Just a normal control class. eventHandler( event, $( this ) ); // Handle the event. close(); // Close Slidebar. } } ); // Close Slidebar via site $site.on( 'touchend click', function ( event ) { if ( settings.siteClose && ( leftActive || rightActive ) ) { // If settings permit closing by site and left or right Slidebar is open. eventHandler( event, $( this ) ); // Handle the event. close(); // Close it. } } ); }; // End Slidebars function. } ) ( jQuery );