Showing posts with label Rotating Content. Show all posts
Showing posts with label Rotating Content. Show all posts

Friday, October 7, 2011

Rotating Selectable Slideshow

This is the third post in the rotating content and tabs series that explores CSS, JavaScript, HTML and JQuery. This time we create a news rotator with slide index, next and previous buttons, auto forward, and a play/pause button. Moreover, it degrafes fairly nicely without JavaScript turned on, which should lend itself to decent accessibility by screen readers and other assistive technologies. It can currently be seen on this test page: https://cms.uwm.edu/letsci/chemistry/testslider.cfm.

The CSS:
#slideshow #slidesContainer 
{
  margin:0 auto;
  width:560px;
  height:263px;
  overflow:auto; /* allow scrollbar when no JS. you may want to add instead overflow-x:hidden; overflow-y: scroll;*/
  position:relative;
}

#slideshow #slidesContainer .slide 
{
  margin:0 auto;
  width:580px; /* reduce by 20 pixels to avoid horizontal scroll */
  height:150px;
}

.control 
{
  display:block;
  width:39px;
  height:263px;
  text-indent:-10000px;
  position:absolute;
  cursor: pointer;
}

#leftControl 
{
  top:0;
  left:0;
  background:transparent url(/letsci/assets/images/testprev.png) no-repeat 0 0;
}

#rightControl
{
  top:0;
  right:0;
  background:transparent url(/letsci/assets/images/testnext.png) no-repeat 0 0;
}

a.slidelinks, 
a.playpause
{
  color: #ff0505;
}

.slideDesc 
{
  position:relative;
  top:-20px;
  height:20px;
  background:black;
  opacity:0.7;
  filter:alpha(opactiy=70);
  color:white;
}

.slideindex 
{
  display: block;
  float: right;
  margin-right: 130px;
}
The HTML:
<div id="slideshow">
  <div id="slidesContainer">

    <div class="slide">
      <a href="http://jastreich.com/"><img src="images/1.png" alt="Image alt" /></a>
      <div class="slideDesc">Slide 1.
      <span class="slideindex">
        <b>1</b>
        <a class="slidelinks" href="javascript:" onclick="pause();gotoslide(1);">2</a>
        <a class="playpause" href="javascript:" onclick="toggle_pause();">Pause</a></span>
    </div>

    <div class="slide">
      <a href="http://slashdot.org/"><img src="images/2.png" alt="Image alt" /></a>
      <div class="slideDesc">Slide 2.
      <span class="slideindex">
        <a class="slidelinks" href="javascript:" onclick="pause();gotoslide(0);">1</a>
        <b>2</b>
        <a class="playpause" href="javascript:" onclick="toggle_pause();">Pause</a></span>
    </div>

  </div>
</div>
The JavaScript:

  var currentPosition = 0;
  var slideWidth = 600;
  var slides = $('.slide');
  var numberOfSlides = slides.length;
  var paused = false;

  // Remove scrollbar in JS
  $('#slidesContainer').css('overflow', 'hidden');

  // Wrap all .slides with #slideInner div
  slides
  .wrapAll('<div id="slideInner"></div>')

  // Float left to display horizontally, readjust .slides width
  .css({
    'float' : 'left',
    'width' : slideWidth
  });

  // Set #slideInner width equal to total width of all slides
  $('#slideInner').css('width', slideWidth * numberOfSlides);

  // Insert left and right arrow controls in the DOM
  $('#slideshow')
    .prepend('<span class="control" id="leftControl">Move left</span>')
    .append('<span class="control" id="rightControl">Move right</span>');

  // Hide left arrow control on first load
  manageControls(currentPosition);

  // Create event listeners for .controls clicks
  $('.control')
    .bind('click', function(){
    // Determine new position
      currentPosition = ($(this).attr('id')=='rightControl')
    ? currentPosition+1 : currentPosition-1;

      // Hide / show controls
      manageControls(currentPosition);
      // Move slideInner using margin-left
      $('#slideInner').animate({
        'marginLeft' : slideWidth*(-currentPosition)
      });
    });

  // Advance on time -- autoforward
  function timeForward()
  {
    if(!paused)
    {
      if(currentPosition + 1 < numberOfSlides)
      {
        gotoslide(currentPosition + 1);
      }
      else
      {
        gotoslide(0);
      }
      setTimeout("timeForward()",3000);
    }
  }

  // Swtich from play to pause
  function toggle_pause()
  {
    if(paused)
    {
      play();
    }
    else
    {
      pause();
    }
  }

  function pause()
  {
      //stop advance, switch button text.
      paused = true;
      $('.playpause').html('play');
  }

  function play()
  {
      //start advance, switch button text.
      paused = false;
      $('.playpause').html('Pause');
      timeForward();
  }

  // manageControls: Hides and shows controls depending on currentPosition
  function manageControls(position)
  {
    // Hide left arrow if position is first slide
    if(position==0){ $('#leftControl').hide() }
    else{ $('#leftControl').show() }
    // Hide right arrow if position is last slide
    if(position==numberOfSlides-1){ $('#rightControl').hide() }
    else{ $('#rightControl').show() }
  }

  // Go to a given slide.
  function gotoslide(i)
  {
    currentPosition = i;
    manageControls(currentPosition);
      $('##slideInner').animate({
        'marginLeft' : slideWidth*(-currentPosition)
      });
  }

  // Start auto advance.
  setTimeout("timeForward()",3000);

Monday, July 18, 2011

Rotating Content

Sorry for the delay in posting the second part of this series. I've been busy with meetings and coding and forgot to post the second and third parts. Here is the second, Rotating content. Again, minimal use of JQuery could be replaced with straight JavavScript to lighten the load times. Simple and clean.

The HTML:
<!--- The Container to rotate through --->
<div id="banner"><a href="#" class="bannerpane">
  <!--- Anything with the class bannerpane inside the banner will be looped through.  It doesn't have to be a link, it could a div containing just about anything. Order of children elements will be order they rotate. --->
  <img src="/letsci/images/pollen_1.png" alt="pollen" title="pollen" class="bannerpane"/>
  </a> <a class="bannerpane" href="/letsci/3"><img src="/letsci/images/starts.png" alt="stars" title="stars" />
</a></div>


The CSS:
/* Use a fixed hight and overflow hidden or at the point it rotates you'll see both stories for a short time.  The other solution is to position the .banner absolutely (which would yield a better transition. */
/* Black background was the best thing to fade to for the images I'm using, if you want to fade to white or another color, set the background here to your color of choice. */
#banner {height:156px;overflow:hidden;background:black;}


The JavaScript:
// To start hide them all except the first,
// you may want to do this with inline style instead of JS,
// in case the user doesn't have JavaScript enabled...  I didn't do that to this, yet.
$('.bannerpane').hide();
$('.bannerpane').first().show();

//function that does the swap.
function rotate() {
  //Basically fade out the current, move it to the bottom, fade in the the new top element.
  // The two 5000's control the length of the fade.  These can be adjusted to taste. 
    $("#banner .bannerpane").first().fadeIn(5000).appendTo('#banner').fadeOut(5000);

    // Recursively call this function again in 7000 microseconds
    // The 7000 can be adjusted to taste.
    setTimeout(rotate, 7000);
}

//Call it the first time.
rotate();