/* * 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 += '
' + $(element).html() + '
'; }); // Renaming ids and classes if(settings.renaming) { var $htmlContent = $('
').html(htmlContent); $htmlContent.find('*').each(function(index, element) { var $element = $(element); privateMethods.addPrefix($element); }); htmlContent = $htmlContent.html(); } privateMethods.loadContent($sideMenu, htmlContent); } else if(settings.source !== null) { $.error('Invalid Sidr Source'); } return this.each(function(){ var $this = $(this), data = $this.data('sidr'); // If the plugin hasn't been initialized yet if ( ! data ) { $this.data('sidr', name); $this.click(function(e) { e.preventDefault(); methods.toogle(name); }); } }); }; })( jQuery ); ; // Sticky Plugin v1.0.3 for jQuery // ============= // Author: Anthony Garand // Improvements by German M. Bravo (Kronuz) and Ruud Kamphuis (ruudk) // Improvements by Leonardo C. Daronco (daronco) // Created: 02/14/2011 // Date: 07/20/2015 // Website: http://stickyjs.com/ // Description: Makes an element on the page stick on the screen as you scroll // It will only set the 'top' and 'position' of your element, you // might need to adjust the width in some cases. (function (factory) { if (typeof define === 'function' && define.amd) { // AMD. Register as an anonymous module. define(['jquery'], factory); } else if (typeof module === 'object' && module.exports) { // Node/CommonJS module.exports = factory(require('jquery')); } else { // Browser globals factory(jQuery); } }(function ($) { var slice = Array.prototype.slice; // save ref to original slice() var splice = Array.prototype.splice; // save ref to original slice() var defaults = { topSpacing: 0, bottomSpacing: 0, className: 'is-sticky', wrapperClassName: 'sticky-wrapper', center: false, getWidthFrom: '', widthFromWrapper: true, // works only when .getWidthFrom is empty responsiveWidth: false }, $window = $(window), $document = $(document), sticked = [], windowHeight = $window.height(), scroller = function() { var scrollTop = $window.scrollTop(), documentHeight = $document.height(), dwh = documentHeight - windowHeight, extra = (scrollTop > dwh) ? dwh - scrollTop : 0; for (var i = 0, l = sticked.length; i < l; i++) { var s = sticked[i], elementTop = s.stickyWrapper.offset().top, etse = elementTop - s.topSpacing - extra; //update height in case of dynamic content s.stickyWrapper.css('height', s.stickyElement.outerHeight()); if (scrollTop <= etse) { if (s.currentTop !== null) { s.stickyElement .css({ 'width': '', 'position': '', 'top': '' }); s.stickyElement.parent().removeClass(s.className); s.stickyElement.trigger('sticky-end', [s]); s.currentTop = null; } } else { var newTop = documentHeight - s.stickyElement.outerHeight() - s.topSpacing - s.bottomSpacing - scrollTop - extra; if (newTop < 0) { newTop = newTop + s.topSpacing; } else { newTop = s.topSpacing; } if (s.currentTop !== newTop) { var newWidth; if (s.getWidthFrom) { newWidth = $(s.getWidthFrom).width() || null; } else if (s.widthFromWrapper) { newWidth = s.stickyWrapper.width(); } if (newWidth == null) { newWidth = s.stickyElement.width(); } s.stickyElement .css('width', newWidth) .css('position', 'fixed') .css('top', newTop); s.stickyElement.parent().addClass(s.className); if (s.currentTop === null) { s.stickyElement.trigger('sticky-start', [s]); } else { // sticky is started but it have to be repositioned s.stickyElement.trigger('sticky-update', [s]); } if (s.currentTop === s.topSpacing && s.currentTop > newTop || s.currentTop === null && newTop < s.topSpacing) { // just reached bottom || just started to stick but bottom is already reached s.stickyElement.trigger('sticky-bottom-reached', [s]); } else if(s.currentTop !== null && newTop === s.topSpacing && s.currentTop < newTop) { // sticky is started && sticked at topSpacing && overflowing from top just finished s.stickyElement.trigger('sticky-bottom-unreached', [s]); } s.currentTop = newTop; } } } }, resizer = function() { windowHeight = $window.height(); for (var i = 0, l = sticked.length; i < l; i++) { var s = sticked[i]; var newWidth = null; if (s.getWidthFrom) { if (s.responsiveWidth) { newWidth = $(s.getWidthFrom).width(); } } else if(s.widthFromWrapper) { newWidth = s.stickyWrapper.width(); } if (newWidth != null) { s.stickyElement.css('width', newWidth); } } }, methods = { init: function(options) { var o = $.extend({}, defaults, options); return this.each(function() { var stickyElement = $(this); var stickyId = stickyElement.attr('id'); var stickyHeight = stickyElement.outerHeight(); var wrapperId = stickyId ? stickyId + '-' + defaults.wrapperClassName : defaults.wrapperClassName; var wrapper = $('
') .attr('id', wrapperId) .addClass(o.wrapperClassName); stickyElement.wrapAll(wrapper); var stickyWrapper = stickyElement.parent(); if (o.center) { stickyWrapper.css({width:stickyElement.outerWidth(),marginLeft:"auto",marginRight:"auto"}); } if (stickyElement.css("float") === "right") { stickyElement.css({"float":"none"}).parent().css({"float":"right"}); } stickyWrapper.css('height', stickyHeight); o.stickyElement = stickyElement; o.stickyWrapper = stickyWrapper; o.currentTop = null; sticked.push(o); }); }, update: scroller, unstick: function(options) { return this.each(function() { var that = this; var unstickyElement = $(that); var removeIdx = -1; var i = sticked.length; while (i-- > 0) { if (sticked[i].stickyElement.get(0) === that) { splice.call(sticked,i,1); removeIdx = i; } } if(removeIdx !== -1) { unstickyElement.unwrap(); unstickyElement .css({ 'width': '', 'position': '', 'top': '', 'float': '' }) ; } }); } }; // should be more efficient than using $window.scroll(scroller) and $window.resize(resizer): if (window.addEventListener) { window.addEventListener('scroll', scroller, false); window.addEventListener('resize', resizer, false); } else if (window.attachEvent) { window.attachEvent('onscroll', scroller); window.attachEvent('onresize', resizer); } $.fn.sticky = function(method) { if (methods[method]) { return methods[method].apply(this, slice.call(arguments, 1)); } else if (typeof method === 'object' || !method ) { return methods.init.apply( this, arguments ); } else { $.error('Method ' + method + ' does not exist on jQuery.sticky'); } }; $.fn.unstick = function(method) { if (methods[method]) { return methods[method].apply(this, slice.call(arguments, 1)); } else if (typeof method === 'object' || !method ) { return methods.unstick.apply( this, arguments ); } else { $.error('Method ' + method + ' does not exist on jQuery.sticky'); } }; $(function() { setTimeout(scroller, 0); }); })); ;