I'm trying to create a sliding sidebar and was wondering if there was a better way then what I am doing already.
<img id = "MenuIcon" src = "MenuIcon.png" alt = "Menu Icon" onclick = "slideSideBar()" />
At the moment I simply check if the sideSlideCount is even - if it is the sidebar must not be out, so when the function is called it slides out; if sideSlideCount is odd (i.e. % 2 != 0) then the sidebar should slide out of view.
var sideSlideCount = 0; // variable used with the side bar
var bodyHeight = $(window).height();
var bodyWidth = $(window).width();
console.log(bodyWidth);
function slideSideBar() {
if (sideSlideCount % 2 == 0) { // if sideSlideCount is even, i.e. the side bar is hidden
$("#SideBar").animate({width: bodyWidth / 6}, 600); // slide the bar out to 300 width, 0.6 seconds
$("#SideLinks").fadeTo(1000, 0.8); // fade the links into view, 1 second, to 100% opacity
}
else { // else, if the side bar is in view
$("#SideBar").fadeIn(300).animate({width: 0}, 600); // slide the bar back out of view (0 width), 0.6 seconds
$("#SideLinks").fadeTo(200, 0); // fade the links out of view, 0.2 seconds, to 0% opacity
}
sideSlideCount++; // increment the variable
}
3 Answers 3
You could simply make your code modular to avoid global variables. You should be looking into AMD modules, however to keep it simple you can create yourself a namespace where your code will live.
DEMO: http://jsfiddle.net/BzYuQ/
//Define a SlidingSidebar reusable component
!function (ns, $) {
function SlidingSidebar(el, animateDuration) {
this.$el = $(el);
this.animateDuration = animateDuration;
}
SlidingSidebar.prototype = {
constructor: SlidingSidebar,
toggle: function () {
this.$el.stop().animate({ width: 'toggle' }, this.animateDuration);
}
};
ns.SlidingSidebar = SlidingSidebar;
}(slideExampleSite = window.slideExampleSite || {}, jQuery);
$(function () {
//The following behavior could also be in a configurable "SlidebarFeature" module
//or you could integrate the button directly into the SlidingSidebar.
//I'm just showing how code can be modularized here.
var sideBar = new slideExampleSite.SlidingSidebar('#sidebar', 600);
$('#toggle-btn').click(function () {
sideBar.toggle();
});
});
Obviously in this case the SlidingSidebar component doesn't do much, but as your application grows, modularizing your code to get away from the $(function () {/*tons of code*/}); anti-pattern will pay off in many ways.
Comments
You didn't say what "better" is, but if the intention is just to avoid globals, you can use a closure:
var slideSideBar = (function() {
var sideSlideCount = false; // variable used with the side bar
var bodyHeight = $(window).height();
var bodyWidth = $(window).width();
console.log(bodyWidth);
// This function has access to all the above variables, but no other
// function does.
function slideSideBar() {
if (sideSlideCount) {
$("#SideBar").animate({width: bodyWidth / 6}, 600);
$("#SideLinks").fadeTo(1000, 0.8);
} else {
$("#SideBar").fadeIn(300).animate({width: 0}, 600);
$("#SideLinks").fadeTo(200, 0);
}
sideSlideCount = !sideSlideCount;
}
// Return a reference to the slideSideBar function so it's available
// globally, but access to variables is "private"
return slideSideBar;
}());
The only difference is that slideSideBar won't exist until the above has been executed, so don't try to call it until afterward.
Comments
Not sure on your definition of "better", but I see your using jQuery which has a nice $toggle feature which can help here.
function slidesideBar(){
$("#SideBar").toggle(function() {
$(this).animate({width: bodyWidth / 6}, 600); // slide the bar out to 300 width, 0.6 seconds
$("#SideLinks").fadeTo(1000, 0.8); // fade the links into view, 1 second, to 100% opacity
}, function() {
$(this).fadeIn(300).animate({width: 0}, 600); // slide the bar back out of view (0 width), 0.6 seconds
$("#SideLinks").fadeTo(200, 0); // fade the links out of view, 0.2 seconds, to 0% opacity
});
}
Credit: jQuery Animation Toggle. Copy and paste:
When given a list of functions as arguments, the .toggle(fn1, fn2) method will alternate between the functions given starting with the first one. This automatically keeps track of the toggle state for you - you don't have to do that.
jQuery doc is here. There are multiple forms of .toggle() depending upon the arguments used so you don't always find the right one when searching the jQuery doc.
if (sideSlideCount%2 == 0), you can swap the blocks and useif (sideSlideCount%2). You could also doif (sideSlideCount)and latersideSlideCount = ++sideSlideCount%2or evensideSlideCount = !sideSlideCount.slideSideBar?