tags:

views:

110

answers:

3

I'm trying to make a sliding panel using .animate function because I want it to slide left/right (jQuery allow slideUp and slideDown, but no other directions). I made the animation like this :

jQuery('#slide1-button').toggle(
function(){jQuery('#slide1').animate({right: 700},600);},
function(){jQuery('#slide1').animate({right: -700},600);}
);

jQuery('#slide2-button').toggle(
function(){jQuery('#slide2').animate({right: 700},600);},
function(){jQuery('#slide2').animate({right: -700},600);}
);

jQuery('#slide3-button').toggle(
function(){jQuery('#slide3').animate({right: 700},600);},
function(){jQuery('#slide3').animate({right: -700},600);}
);

Now I would like the opened panel to hide when I open an other one.

EDIT: here is the markup :

<ul>
<li id="slide1-button" class="slideButton">Entreprise</li>
<li id="slide2-button" class="slideButton">Culture</li>
<li id="slide3-button" class="slideButton">Institution</li>
</ul>

<div id="slide-wrapper">

<div id="slide1" class="slide">
<span class="closeall"></span><!-- content -->
</div>

<div id="slide2" class="slide">
<span class="closeall"></span><!-- content -->
</div>

<div id="slide3" class="slide">
<span class="closeall"></span><!-- content -->
</div>

</div> <!-- /#slide-wrapper -->
A: 

If you assign a class to the slides, like "slide", you can generalize your code and write something like (not tested):

jQuery('.slide [id$=button]').toggle(
    function(){ jQuery(this).closest('.slide').animate({ right: 700 }, 600);
                jQuery('.slide [id$=button]').not(this).toggle(); },
    function(){ jQuery(this).closest('.slide').animate({ right: -700 }, 600); }
);
tanathos
A: 

I am not familiar with jQuery, but here is a possible way to refactor your code:

  1. Create an array for your slides
  2. Set an "open" property for each slide
  3. Whenever you open a slide, loop through the array, and if a slide has the "open" property set to "true", close it.

Possible code:

var slides = [];
slides[0] = $("#slide1")[0];
slides[1] = $("#slide2")[0];
slides[2] = $("#slide3")[0];

for (var i=0;i<slides.length;i++) {
    slides[i].open = false;
}

function closeOtherSlides(currentSlide) {
   for (var i=0;i<slides.length;i++) {
    if (slides[i] !== currentSlide && slides[i].open === true) {
      slides[i].animate({right: -700},600);
      slides[i].open = false;
     }
   }
  currentSlide.open = true;
}

jQuery('#slide1-button').toggle(
function(){jQuery('#slide1').animate({right: 700},600);closeOtherSlides(slides[0]);},
function(){jQuery('#slide1').animate({right: -700},600);}
);

jQuery('#slide2-button').toggle(
function(){jQuery('#slide2').animate({right: 700},600);closeOtherSlides(slides[1]);},
function(){jQuery('#slide2').animate({right: -700},600);}
);

jQuery('#slide3-button').toggle(
function(){jQuery('#slide3').animate({right: 700},600);closeOtherSlides(slides[2]);},
function(){jQuery('#slide3').animate({right: -700},600);}
);
Jeff Fohl
+1  A: 

Without changing your markup at all, you could do this:

jQuery('#slide1-button, #slide2-button, #slide3-button').toggle(function(){
  var id = this.id.replace('-button','');
  jQuery('#slide1, #slide2, #slide3').filter(':visible').not('#' + id).animate({right: -700},600);
  jQuery('#' + id).animate({right: 700},600);
}, function(){
  jQuery('#' + this.id.replace('-button','')).animate({right: -700},600);
});

But...I would advise putting a class on your slide# and slide#-button elements, if your buttons had .slideButton and your divs had .slide, you could do this:

jQuery('.slideButton').toggle(function(){
  var id = this.id.replace('-button','');
  jQuery('.slide:visible').not('#' + id).animate({right: -700},600);
  jQuery('#' + id).animate({right: 700},600);
}, function(){
  jQuery('#' + this.id.replace('-button','')).animate({right: -700},600);
});

Without knowing what type of elements the slide buttons are I can't say further how to optimize this, but using something like rel="#slide1" would be even cleaner/less code.

Nick Craver
this solution seems suitable but I have a new issue : to toggle a second time, I need to click twice.For example, I open slide1, then slide2, and want to open again slide1. The first click on slide1-button does nothein, the second does the toggle...I will edit my post to show you the html
Mael
here is the reason : "Since .toggle() internally uses a click handler to do its work, we must unbind click to remove a behavior attached with .toggle(), so other click handlers can be caught in the crossfire."http://api.jquery.com/toggle/I'm not sure where to place that unbid() method.
Mael