I'm fairly new to JS/jQuery (a few months), and I think it's time to start getting involved in the community. So I wrote a little plugin. Nothing revolutionary. Really, the project is to write a clean, workable plugin. Any and all thoughts and suggestions on how I can make the code cleaner, or the animations smoother, or anything, are very much appreciated.
Here's the plugin in action: http://jsfiddle.net/VA7P5/
Here is the plugin code:
(function ($) {
$.fn.menuBar = function (options) {
var defaults = {
width: 145, // Width of Sidebar
left: true, // If true, sidebar is positioned left. If false, it's positioned right
height: 80, // Height of footer
barColor: '#000', // Color of three-bar menu before it's opened
menuBackground: '#303030', // Background color of sidebar and footer
closeColor: '#fff' // Color of close-button
};
var options = $.extend(defaults, options);
return this.each(function () {
var i = $(this);
var o = options;
var width = $('nav.sidebar').css('width');
var height = $('footer.hidden').css('height');
var closeColor = $('.bar').css('background');
var barColor = $('.bar').css('background');
var barOne = $('.menu-bar-top');
var barTwo = $('.menu-bar-bottom');
var barThree = $('.menu-bar-mid');
var menuTrigger = $('nav.sidebar a');
var fadeWrapper = $('#fade-wrapper');
var nav = $('nav.sidebar');
var footerHidden = $('footer.hidden');
var bar = $('.bar');
bar.css('background', o.barColor);
if (o.left) {
nav.css({
'width': o.width,
'left': o.width - (o.width * 2),
'background': o.menuBackground
});
$('.menu-trigger').css({
'left': 0
});
} else {
nav.css({
'width': o.width,
'right': o.width - (o.width * 2),
'background': o.menuBackground
});
$('.menu-trigger').css({
'right': 0
});
}
footerHidden.css({
'height': o.height,
'bottom': o.height - (o.height * 2),
'background': o.menuBackground
});
i.click(function(){
if (i.hasClass('open')) {
closeMenu();
i.removeClass('open');
// Allow scrolling again when menu is closed
$('body').css('overflow', '');
} else {
openMenu();
i.addClass('open');
// No scrolling while menu is open
$('body').css('overflow', 'hidden');
}
});
$('#fade-wrapper').click(function(){
closeMenu();
i.removeClass('open');
$('body').css('overflow', '');
});
/*===========================================================================================================
Opening/Closing Functions
===========================================================================================================*/
function openMenu() {
fadeWrapper.fadeIn(100, function(){
barOne.css({
'top': '8px',
'transform': 'rotate(405deg)',
'-webkit-transform': 'rotate(405deg)',
'-moz-transform': 'rotate(405deg)',
'-ms-transform': 'rotate(405deg)',
'-o-transform': 'rotate(405deg)'
});
barTwo.css({
'top': '8px',
'transform': 'rotate(-405deg)',
'-webkit-transform': 'rotate(-405deg)',
'-moz-transform': 'rotate(-405deg)',
'-ms-transform': 'rotate(-405deg)',
'-o-transform': 'rotate(-405deg)'
});
if (o.left) {
nav.animate({'left': '+=' + o.width}, 200);
} else {
nav.animate({'right': '+=' + o.width}, 200);
}
footerHidden.animate({'bottom': '+=' + o.height}, 200);
barThree.fadeOut(100);
bar.css('background', o.closeColor);
});
}
function closeMenu() {
setTimeout(function(){
barThree.fadeTo(100, 1);
fadeWrapper.fadeOut(100);
if (o.left) {
nav.animate({'left': '-=' + o.width}, 200);
} else {
nav.animate({'right': '-=' + o.width}, 200);
}
footerHidden.animate({'bottom': '-=' + o.height}, 200);
bar.css('background', o.barColor);
barOne.css({
'top': '3px',
'transform': 'rotate(360deg)',
'-webkit-transform': 'rotate(360deg)',
'-moz-transform': 'rotate(360deg)',
'ms-transform': 'rotate(360deg)',
'o-transform': 'rotate(360deg)'
});
barTwo.css({
'top': '13px',
'transform': 'rotate(-360deg)',
'-webkit-transform': 'rotate(-360deg)',
'-moz-transform': 'rotate(-360deg)',
'-ms-transform': 'rotate(-360deg)',
'-o-transform': 'rotate(-360deg)'
});}, 1);
}
});
};
})(jQuery);
The necessary HTML:
<nav class="sidebar">
<a class="menu cursor" title="Menu">
<div class="menu-trigger">
<div class="bar-container">
<div class="bar menu-bar-top"></div>
<div class="bar menu-bar-mid"></div>
<div class="bar menu-bar-bottom"></div>
</div>
</div>
</a>
<!-- Sidebar content goes here -->
</nav>
<div id="fade-wrapper"></div>
<footer class="hidden">
<!-- Footer content goes here -->
</footer>
The necessary CSS:
a.cursor {
cursor: pointer;
}
#fade-wrapper {
display: none;
position: fixed;
top: 0;
left: 0;
height: 100%;
width: 100%;
background: rgba(0, 0, 0, 0.3);
z-index: 5000;
}
nav.sidebar {
position: fixed;
top: 0;
height: 100%;
z-index: 9999;
}
.menu-trigger {
position: fixed;
top: 8px;
width: 40px;
height: 20px;
line-height: 40px;
}
.bar-container {
margin-top: 3px;
height: 13px;
}
.bar {
position: absolute;
height: 3px;
width: 90%;
outline: 1px solid transparent;
-webkit-transition: all .5s ease;
-moz-transition: all .5s ease;
-ms-transition: all .5s ease;
-o-transition: all .5s ease;
transition: all .5s ease;
}
.menu-bar-top {
top: 3px;
left: 2px;
}
.menu-bar-mid {
top: 8px;
left: 2px;
}
.menu-bar-bottom {
top: 13px;
left: 2px;
}
footer.hidden {
position: fixed;
left: 0;
width: 100%;
z-index: 9999;
}
1 Answer 1
I like your code, it is easy to follow, has comments, well named variables etc. The only thing I would point out is that you are repeating yourself here and there. So I will focus on that:
This piece of code:
if (o.left) { nav.css({ 'width': o.width, 'left': o.width - (o.width * 2), 'background': o.menuBackground }); $('.menu-trigger').css({ 'left': 0 }); } else { nav.css({ 'width': o.width, 'right': o.width - (o.width * 2), 'background': o.menuBackground }); $('.menu-trigger').css({ 'right': 0 }); }
Is really repeating the same thing but with
left
being replaced withright
, you could just assignleft
orright
to a variable first.var key = o.left ? 'left' : 'right'; nav.css({ 'width': o.width, 'background': o.menuBackground }).css( key, o.width - (o.width * 2) ); $('.menu-trigger').css( key , 0 );
This piece of code is repeated a few times at well, the only different is the degrees and the value of
'top'
.barTwo.css({ 'top': '13px', 'transform': 'rotate(-360deg)', '-webkit-transform': 'rotate(-360deg)', '-moz-transform': 'rotate(-360deg)', '-ms-transform': 'rotate(-360deg)', '-o-transform': 'rotate(-360deg)' });}, 1);
You could consider a helper function that this transformation for you
function generateTransformation( top , transformation ){ return { 'top': top, 'transform': transformation, '-webkit-transform': transformation, '-moz-transform': transformation, '-ms-transform': transformation, '-o-transform': transformation' }; }
Then, you can simply do
barOne.css( generateTransformation( '3px' , 'rotate(360deg)' )); barTwo.css( generateTransformation( '13px' , 'rotate(-360deg)' ));
These:
if (o.left) { nav.animate({'left': '+=' + o.width}, 200); } else { nav.animate({'right': '+=' + o.width}, 200); }
I will leave to you as an exercise for the reader.
var bar = $('.bar');
<- This will select 3 bars, perhaps call itbars
?var closeColor = $('.bar').css('background');
<- This takes the background color of the first bar, I would put that in a comment or make it more obvious by calling$('.bar').eq(0).css('background');
or even better determinebars
first and then go forbars.eq(0).css('background');
-
\$\begingroup\$ Thanks a ton! This kind of feedback is exactly what I'm looking for. I want to post an update, but before I do: Should I A) replace the code in the original post with the new code, B) Add the new code block to the original post or C) post the new code block as an answer? \$\endgroup\$Justin– Justin2014年04月21日 17:49:30 +00:00Commented Apr 21, 2014 at 17:49
-
\$\begingroup\$ You are welcome, Option C is the way to go. \$\endgroup\$konijn– konijn2014年04月21日 18:08:27 +00:00Commented Apr 21, 2014 at 18:08
-
\$\begingroup\$ I just posted the update. I've got a quick question, though: Why is it that
elem.css(var, var)
works, butelem.css({var: var})
does not? \$\endgroup\$Justin– Justin2014年04月21日 18:47:26 +00:00Commented Apr 21, 2014 at 18:47 -
\$\begingroup\$ Gah, I meant Option D -> New Question, my bad, I misread your options \$\endgroup\$konijn– konijn2014年04月21日 18:49:41 +00:00Commented Apr 21, 2014 at 18:49
-
1\$\begingroup\$ Last comment, though feel free to ask questions in Chat ( chat.stackexchange.com/rooms/8595/the-2nd-monitor ) by addressing @Konijn, that would really be an SO question, I cant tell off hand what is going on. \$\endgroup\$konijn– konijn2014年04月21日 19:20:10 +00:00Commented Apr 21, 2014 at 19:20
Explore related questions
See similar questions with these tags.