You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
260 lines
7.5 KiB
260 lines
7.5 KiB
/*
|
|
* 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-id-$1'));
|
|
}
|
|
if(typeof elementClass === 'string' && '' !== elementClass && 'sidr-inner' !== elementClass) {
|
|
$element.attr('class', elementClass.replace(/([A-Za-z0-9_.\-]+)/g, 'sidr-class-$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'),
|
|
menuWidth = $menu.outerWidth(true),
|
|
speed = $menu.data('speed'),
|
|
side = $menu.data('side'),
|
|
bodyAnimation,
|
|
menuAnimation,
|
|
scrollTop;
|
|
|
|
// Open Sidr
|
|
if('open' === action || ('toogle' === action && !$menu.is(':visible'))) {
|
|
// Check if we can open it
|
|
if( $menu.is(':visible') || 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'};
|
|
menuAnimation = {left: '0px'};
|
|
}
|
|
else {
|
|
bodyAnimation = {right: menuWidth + 'px'};
|
|
menuAnimation = {right: '0px'};
|
|
}
|
|
|
|
// Prepare page
|
|
scrollTop = $html.scrollTop();
|
|
$html.css('overflow-x', 'hidden').scrollTop(scrollTop);
|
|
|
|
// Open menu
|
|
$body.css({
|
|
position: 'absolute',
|
|
width: $body.width()
|
|
}).animate(bodyAnimation, speed);
|
|
$menu.css('display', 'block').animate(menuAnimation, speed, function() {
|
|
sidrMoving = false;
|
|
sidrOpened = name;
|
|
// Callback
|
|
if(typeof callback === 'function') {
|
|
callback(name);
|
|
}
|
|
});
|
|
}
|
|
// Close Sidr
|
|
else {
|
|
// Check if we can close it
|
|
if( !$menu.is(':visible') || sidrMoving ) {
|
|
return;
|
|
}
|
|
|
|
// Lock sidr
|
|
sidrMoving = true;
|
|
|
|
// Right or left menu?
|
|
if(side === 'left') {
|
|
bodyAnimation = {left: 0};
|
|
menuAnimation = {left: '-' + menuWidth + 'px'};
|
|
}
|
|
else {
|
|
bodyAnimation = {right: 0};
|
|
menuAnimation = {right: '-' + menuWidth + 'px'};
|
|
}
|
|
|
|
// Close menu
|
|
scrollTop = $html.scrollTop();
|
|
$html.removeAttr('style').scrollTop(scrollTop);
|
|
$body.animate(bodyAnimation, speed);
|
|
$menu.animate(menuAnimation, speed, function() {
|
|
$menu.removeAttr('style');
|
|
$body.removeAttr('style');
|
|
$('html').removeAttr('style');
|
|
sidrMoving = false;
|
|
sidrOpened = false;
|
|
// Callback
|
|
if(typeof callback === 'function') {
|
|
callback(name);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
};
|
|
|
|
// Sidr public methods
|
|
var methods = {
|
|
open: function(name, callback) {
|
|
privateMethods.execute('open', name, callback);
|
|
},
|
|
close: function(name, callback) {
|
|
privateMethods.execute('close', 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,
|
|
}, options);
|
|
|
|
var name = settings.name,
|
|
$sideMenu = $('#' + name);
|
|
|
|
// If the side menu do not exist create it
|
|
if( $sideMenu.length === 0 ) {
|
|
$sideMenu = $('<div />')
|
|
.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
|
|
});
|
|
|
|
// 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 += '<div class="sidr-inner">' + $(element).html() + '</div>';
|
|
});
|
|
|
|
// Renaming ids and classes
|
|
if(settings.renaming) {
|
|
var $htmlContent = $('<div />').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 );
|