views:

2417

answers:

2

Hi there,

I'm trying to recreate the effect shown on the BBC homepage where the links 'add more to this page' and 'set location' slide open their corresponding divs and show their relevant content. If you select 'add more to this page' it slides open the 'add more' section. If you select 'add more to this page' again it then closes the 'add more' section. However if the 'add more' section is open, and you select 'set location' it slides the 'add more' section up before sliding down the 'set location' select.

I've managed to recreate this effect using the following code:

HTML

 <ul id="demo">
  <li><a href="#sectionOne">Link One <span class="rm">this site</span></a></li>
  <li><a href="#sectionTwo">Link Two</a></li>
  <li><a href="#sectionThree">Link Three</a></li>     
 </ul>

 <div id="siteCustomisation">
  <div class="siteSelection" id="sectionOne">
   <h3>Section One</h3>
   <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla congue tincidunt tortor, id condimentum massa scelerisque id. Cras elit magna, posuere at sollicitudin in, tristique nec turpis.</p>
  </div>
  <div class="siteSelection" id="sectionTwo">
   <h3>Section Two</h3>
   <p>Maecenas condimentum tincidunt pretium. Ut est ipsum, pharetra quis congue eu, eleifend vitae velit. Vestibulum quam purus, posuere quis vehicula ut, sollicitudin vel urna.</p>
  </div>
  <div class="siteSelection" id="sectionThree">
   <h3>Section Three</h3>
   <p>Nulla id nisi eget urna gravida euismod. Mauris tempor, diam ullamcorper sagittis eleifend, urna mauris scelerisque massa, placerat sagittis massa augue nec purus.</p>
  </div>         
 </div>

Jquery Code

$(function(){
 $("#siteCustomisation .siteSelection").hide();

 $("#demo li a").each(function(index) {
  $(this).click(function() { 
   var id = $(this).attr('href');
   var $thisDiv = $(id);

   if ($thisDiv.siblings(':visible').length) { 
    $thisDiv.siblings(':visible').slideUp(700, function() {
     $thisDiv.slideDown();
    });
   } else { 
    $thisDiv.slideToggle();   
   }
   return false;
  });
 });  
});

The problem is, if someone clicks link one, then link two quickly both divs are then displayed on the page. Only one section should be shown at all times. Any ideas how I could fix this issue?

Thank you for your help.

+1  A: 

You could disable click events when you start the sliding and re-enable it when sliding is complete. Even easier, you can use a global variable as a "lock". Set it to false when sliding begins, re-set it to true when it ends. Do not allow sliding for any div when the variable is false. You must use callbacks for all the animations.

You can use something like this:

animationStarted = true;
$thisDiv.slideToggle(function() {   
   animationStarted = false; 
});

All "animation" methods (slideToggle, slideDown) accept a callback function as an argument, which is called when the effect they perform is completed.

kgiannakakis
Hi, thank you for the reply. I'm fairly new to jQuery so I'm not sure how I could test when the sliding effect begins and ends. Are you suggesting I use 'animate' for the sliding effects rather than slideUp etc?
Aemulus
See my edited answer
kgiannakakis
+5  A: 

a quick demo for you here. Basically you can test if any of the divs are currently animating before proceeding with the next slideDown using the :animated selector.

Also take note of the way I use .live. This is preferable than attaching the same event handler to multiple elements.

n.b Ignore the text jump as this is just down to the lack of css

redsquare