0

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
}
4
  • Instead of if (sideSlideCount%2 == 0), you can swap the blocks and use if (sideSlideCount%2). You could also do if (sideSlideCount) and later sideSlideCount = ++sideSlideCount%2 or even sideSlideCount = !sideSlideCount. Commented Jun 25, 2014 at 23:40
  • @RobG I think what I'm interested in here is a way to avoid the global variable sideSlideCount; say the sidebar has a News section, when you click that section it should display more options - this would also need a global variable to keep track of whether it was open or not. It seems like I'm going to end up with a large number of global variables, which I would prefer not to. I could just use a boolean, but even that would have to be boolean. Commented Jun 26, 2014 at 0:01
  • @connor0728 What defines when it's actually getting slided? What calls slideSideBar? Commented Jun 26, 2014 at 0:07
  • @plalx I have a typical 3 bar menu icon, when that is clicked the sideBar slides in/out. I've included the code in the original post now. Commented Jun 26, 2014 at 0:09

3 Answers 3

1

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.

Sign up to request clarification or add additional context in comments.

Comments

1

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

0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.