/* * Sidr * https://github.com/artberri/sidr * * Copyright (c) 2013 Alberto Varela * Licensed under the MIT license. */ ;(function( $ ){ var sidrMoving = false, sidrOpened = false; // Private methods var privateMethods = { // Check for valids urls // From : http://stackoverflow.com/questions/5717093/check-if-a-javascript-string-is-an-url isUrl: function (str) { var pattern = new RegExp('^(https?:\\/\\/)?'+ // protocol '((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|'+ // domain name '((\\d{1,3}\\.){3}\\d{1,3}))'+ // OR ip (v4) address '(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*'+ // port and path '(\\?[;&a-z\\d%_.~+=-]*)?'+ // query string '(\\#[-a-z\\d_]*)?$','i'); // fragment locator if(!pattern.test(str)) { return false; } else { return true; } }, // Loads the content into the menu bar loadContent: function($menu, content) { $menu.html(content); }, // Add sidr prefixes addPrefix: function($element) { var elementId = $element.attr('id'), elementClass = $element.attr('class'); if(typeof elementId === 'string' && '' !== elementId) { $element.attr('id', elementId.replace(/([A-Za-z0-9_.\-]+)/g, 'sidr-$1')); } if(typeof elementClass === 'string' && '' !== elementClass && 'sidr-inner' !== elementClass) { $element.attr('class', elementClass.replace(/([A-Za-z0-9_.\-]+)/g, 'sidr-$1')); } $element.removeAttr('style'); }, execute: function(action, name, callback) { // Check arguments if(typeof name === 'function') { callback = name; name = 'sidr'; } else if(!name) { name = 'sidr'; } // Declaring var $menu = $('#' + name), $body = $($menu.data('body')), $html = $('html'), $topbar = $('#smg-bar'), $stickbar = $('#mobile-header'), menuWidth = $menu.outerWidth(true), speed = $menu.data('speed'), side = $menu.data('side'), displace = $menu.data('displace'), onOpen = $menu.data('onOpen'), onClose = $menu.data('onClose'), bodyAnimation, menuAnimation, scrollTop, bodyClass = (name === 'sidr' ? 'sidr-open' : 'sidr-open ' + name + '-open'); // Open Sidr if('open' === action || ('toogle' === action && !$menu.hasClass('opened') )) { // Check if we can open it if(sidrMoving) { return; } // If another menu opened close first if(sidrOpened !== false) { methods.close(sidrOpened, function() { methods.open(name); }); return; } // Lock sidr sidrMoving = true; // Left or right? if(side === 'left') { bodyAnimation = {left: menuWidth + 'px'}; topBarAnimation = {left: menuWidth + 'px'}; menuAnimation = {left: '0px'}; } else { bodyAnimation = {right: menuWidth + 'px'}; topBarAnimation = {right: menuWidth + 'px'}; menuAnimation = {right: '0px'}; } // Prepare page scrollTop = $html.scrollTop(); //$html.css('overflow-x', 'hidden').scrollTop(scrollTop); // Open menu $body.css({ width: $body.width(), position: 'absolute' }).animate(bodyAnimation, speed); $topbar.animate(topBarAnimation,speed); if($stickbar.parent().hasClass('is-sticky')){ $stickbar.animate(topBarAnimation,speed,function(){ var offset = $stickbar.offset().top - $(window).scrollTop(); $stickbar.removeAttr('style'); $stickbar.css({'top':offset,'position':'fixed'}); $stickbar.addClass('pushed'); }); }else{ $stickbar.addClass('pushed'); } $menu.css({left:'0px'}).animate(menuAnimation, speed, function() { sidrMoving = false; sidrOpened = name; $menu.css({'z-index':10}); $menu.addClass('opened'); // Callback if(typeof callback === 'function') { callback(name); } }); // onOpen Callback onOpen(); // iPad Hack $("header").css("opacity", 0.99); $("header").css("opacity", 1.0); } // Close Sidr else if('close' === action || ('toogle' === action && $menu.hasClass('opened'))){ // Check if we can close it if( !$menu.hasClass('opened') || sidrMoving ) { return; } $menu.css({'z-index':-10}); // Lock sidr sidrMoving = true; // Right or left menu? if(side === 'left') { bodyAnimation = {left: 0}; topBarAnimation = {left: 0}; menuAnimation = {left: 0}; } else { bodyAnimation = {right: 0}; topBarAnimation = {right: 0}; menuAnimation = {left: 0}; } // Close menu scrollTop = $html.scrollTop(); //$html.removeAttr('style').scrollTop(scrollTop); $body.animate(bodyAnimation, speed); $stickbar.css({'position':'relative'}); $stickbar.css({'position':'fixed'}); if($stickbar.parent().hasClass('is-sticky')){ $stickbar.animate(topBarAnimation,speed,function(){ var offset = $stickbar.offset().top - $(window).scrollTop(); $stickbar.removeAttr('style'); $stickbar.css({'top':offset,'position':'fixed'}); $stickbar.removeClass('pushed'); }); }else{ $stickbar.removeAttr('style'); $stickbar.removeClass('pushed'); } $topbar.animate(topBarAnimation, speed); $menu.animate(menuAnimation, speed, function() { $menu.removeAttr('style'); $body.removeAttr('style'); $('html').removeAttr('style'); sidrMoving = false; sidrOpened = false; $menu.removeClass('opened'); // Callback if(typeof callback === 'function') { callback(name); } // onClose Callback onClose(); }); }else if('touchclose' === action){ // Check if we can close it if( !$menu.hasClass('opened') || sidrMoving ) { return; } $menu.css({'z-index':-10}); // Lock sidr sidrMoving = true; // Right or left menu? if(side === 'left') { bodyAnimation = {left:0}; topBarAnimation = {left: 0}; menuAnimation = {left: 0}; } else { bodyAnimation = {right: 0}; topBarAnimation = {right: 0}; menuAnimation = {left: 0}; } //$menu.removeClass('opened'); // Close menu scrollTop = $html.scrollTop(); var currentLeft = menuWidth-$(window).scrollLeft(); //$html.removeAttr('style').scrollTop(scrollTop); $body.animate(bodyAnimation, 0, 'linear'); if($stickbar.parent().hasClass('is-sticky')){ $stickbar.animate(topBarAnimation,0,function(){ var offset = $stickbar.offset().top - $(window).scrollTop(); $stickbar.removeAttr('style'); $stickbar.css({'top':offset,'position':'fixed'}); $stickbar.removeClass('pushed'); } ); }else{ $stickbar.removeAttr('style'); $stickbar.removeClass('pushed'); } $topbar.animate(topBarAnimation, 0,'linear',function() { // $menu.removeAttr('style'); $body.removeAttr('style'); $('html').removeAttr('style'); sidrMoving = false; sidrOpened = false; $menu.removeClass('opened'); // Callback if(typeof callback === 'function') { callback(name); } }); //$menu.animate(menuAnimation, speed); // onClose Callback onClose(); } } }; // Sidr public methods var methods = { open: function(name, callback) { privateMethods.execute('open', name, callback); }, close: function(name, callback) { privateMethods.execute('close', name, callback); }, touchclose: function(name, callback) { privateMethods.execute('touchclose', name, callback); }, toogle: function(name, callback) { privateMethods.execute('toogle', name, callback); } }; $.sidr = function( method ) { if ( methods[method] ) { return methods[method].apply( this, Array.prototype.slice.call( arguments, 1 )); } else if ( typeof method === 'function' || typeof method === 'string' || ! method ) { return methods.toogle.apply( this, arguments ); } else { $.error( 'Method ' + method + ' does not exist on jQuery.sidr' ); } }; $.fn.sidr = function( options ) { var settings = $.extend( { name : 'sidr', // Name for the 'sidr' speed : 200, // Accepts standard jQuery effects speeds (i.e. fast, normal or milliseconds) side : 'left', // Accepts 'left' or 'right' source : null, // Override the source of the content. renaming : true, // The ids and classes will be prepended with a prefix when loading existent content body : 'body', // Page container selector, displace: true, // Displace the body content or not onOpen : function() {}, // Callback when sidr opened onClose : function() {} // Callback when sidr closed }, options); var name = settings.name, $sideMenu = $('#' + name); // If the side menu do not exist create it if( $sideMenu.length === 0 ) { $sideMenu = $('
') .attr('id', name) .appendTo($('body')); } // Adding styles and options $sideMenu .addClass('sidr') .addClass(settings.side) .data({ speed : settings.speed, side : settings.side, body : settings.body, displace : settings.displace, onOpen : settings.onOpen, onClose : settings.onClose }); // The menu content if(typeof settings.source === 'function') { var newContent = settings.source(name); privateMethods.loadContent($sideMenu, newContent); } else if(typeof settings.source === 'string' && privateMethods.isUrl(settings.source)) { $.get(settings.source, function(data) { privateMethods.loadContent($sideMenu, data); }); } else if(typeof settings.source === 'string') { var htmlContent = '', selectors = settings.source.split(','); $.each(selectors, function(index, element) { htmlContent += '