Jay Edwards
Jay Edwards

Reputation: 1035

JS slideshow works one way

My slideshow is suffering from erratic behaviour. it's driven by pagers which the user clicks. when the corresponding pager is clicked, the next image is made visible (opacity/filter) and set as z-index 5 so that it should sit beneath the present image (z-index 10). The current image is then faded-out and finally, the next image is set to current and the image that has faded out is set to z-index 0. However, this only works when clicking back to a previous image (in Chrome, ie is behaving even more strangely.) in the order of images. That is to say,

The pagers and the images are dynamically generated from a database (hence the little piece of PHP at the bottom of the code). it contains as many items as are listed for the page in the database.

a few notes:

1) the fade function is my own take on http://javascript.info/tutorial/animation and has worked just fine in another slideshow elsewhere on the site.

2) getElementsByClass is from http://www.robertnyman.com and returns parent and child elements of the requested class in an array (hence why I call current[0] etc.)

thanks.

<script type="text/javascript">


var pager = document.getElementById('pager1');
var list_pagers = document.getElementById('pagers')
var i = 0;

var next_slide = function(next) {  
  if (next.className !== 'slide_current') {

    if (getElementsByClassName('slide_pending').length === 0) {
      var current = getElementsByClassName('slide_current');
      next.className = 'slide_pending';
      next.style.zIndex = 5;
      next.style.opacity = 1;
      next.style.filter = 'alpha(opacity = 100)';
      next.style.display = 'block';
      fade(current[0], linear, 1000);
      var fadeSlide = switcher(next, current);   
    }
  }  
}

var switcher = function(now, then) {

  setTimeout(function() {
  now.className = 'slide_current';
  now.style.zIndex = 10;
  now.style.opacity = 1;
  now.style.filter = 'alpha(opacity = 100)';

  then[0].className = 'slide_hide';
  then[0].style.zIndex = 0;

  then[0].style.opacity = 0;
  then[0].style.filter = 'alpha(opacity = 0)';
  then[0].style.display = 'none';
  }, 1001);
}

<?php
// dynamically build event for each pager/slide in the show.
for ($k = 1; $k <= $i; $k++) {
  echo  'var next_slide' .$k. ' = document.getElementById("list_slide" +' .$k. '); ',
        'addEvent(list_pagers.childNodes[' .($k - 1). '], "click", function () {next_slide(next_slide' .$k. ')}); ';
}
?>

Upvotes: 2

Views: 175

Answers (2)

Jay Edwards
Jay Edwards

Reputation: 1035

SOLUTION:

the problem was that the <div> tags i was trying to fade each contained an <img> and another <div>... the CSS being applied was either working inconsistently/erratically or - as is IE's wont - not-at-all.... The solution was - rather than animating the fade of the parent <div> - animating the respective child components separately. At first, it looked like the IE solution was completely unto itself; in fact, it was insightful to creating a neat, lightweight non-JQuery slideshow for all the browsers. One trade-off was that I had to incorporate all the styling into the element tags rather than a separate CSS. This seemed like the only viable option in this instance by virtue of the nature of the DOM requests being made... Questions/feedback gratefully received:

 <script type="text/javascript">
var list_pagers = document.getElementById('pagers')
var i = 0;

<?php
// dynamically build event for each pager/slide in the show.
for ($k = 1; $k <= $i; $k++) {
  echo  'var next_slide' .$k. ' = document.getElementById("list_slide" +' .$k. '); ',
        'addEvent(list_pagers.childNodes[' .($k - 1). '], "click", function () {next_slide(next_slide' .$k. ')}); ';
}
?>

var next_slide = function(next) {  
  if (next.className !== 'slide_current') {
      if (navigator.appName === 'Microsoft Internet Explorer') {
        //IE 7 & 8 
        if ((navigator.appVersion.search('MSIE 8.0') >= 1) || (navigator.appVersion.search('MSIE 7.0') >= 1)) {

          var current = getElementsByClassName('slide_current')[0].childNodes[0];
          var currentBar = getElementsByClassName('slide_current')[0].childNodes[1];
          var nextBar = next.childNodes[1]; 
          var nextSlide = next.childNodes[0];
        } else {
        //IE 9
          var current = getElementsByClassName('slide_current')[0].childNodes[1];
          var currentBar = getElementsByClassName('slide_current')[0].childNodes[2];
          var nextBar = next.childNodes[2]; 
          var nextSlide = next.childNodes[1];
        }

        // give the next slide and its header (nextBar) a temporary status of zIndex 5/6
        nextSlide.style.zIndex = 5;
        nextBar.style.zIndex = 6;
        nextSlide.style.filter = "alpha(opacity=100)";
        nextBar.style.filter = "alpha(opacity=85)";

        fade(currentBar, linear, 500); // fade currentBar out
        fade(current, linear, 500); // fade current out

        //once we've faded out current slides, it's time to replace them with th
        setTimeout(function() {
          getElementsByClassName('slide_current')[0].className = 'slide_hide';
          next.className = 'slide_current';
          nextSlide.style.opacity = 1; // IE 9 includes opacity...
          nextBar.style.opacity = 1; // IE 9 includes opacity...
          nextSlide.style.filter = "alpha(opacity=100)";  
          nextBar.style.filter = "alpha(opacity=85)";
          nextSlide.style.zIndex = 10;
          nextBar.style.zIndex = 11;
        }, 500);         

    } else {
      // NON IE TAGS    
      var current = getElementsByClassName('slide_current')[0];
      current.childNodes[1].style.zIndex = 10; // [1] the child <img> tag
      current.childNodes[2].style.zIndex = 11; // [2] the child <div> tag
      current.childNodes[1].style.opacity = 1;
      current.childNodes[2].style.opacity = 0.85;    
      next.childNodes[1].style.zIndex = 5;
      next.childNodes[2].style.zIndex = 6;
      next.childNodes[1].style.opacity = 1;
      next.childNodes[2].style.opacity = 0.85;      
      fade(current.childNodes[1], linear, 600); // fade current out
      fade(current.childNodes[2], linear, 600); // fade current out
      var fadeSlide = setTimeout(function() {switcher(next, current)}, 500); 
      var switcher = function(now, then, nowBar, thenBar) {

        then.className = 'slide_hide';
        then.childNodes[1].style.opacity = 0;
        then.childNodes[2].style.opacity = 0;
        now.className = 'slide_current';  
        now.childNodes[1].style.opacity = 1;
        now.childNodes[2].style.opacity = 0.85;
        now.style.opacity = 1;
      }
    }
  }  
}


</script>

Upvotes: 0

Barney
Barney

Reputation: 1848

Forgive me for not posting an answer to your exact problem, but I would steer away from writing Javascript plugins yourself for the following reasons:

  • Hundreds of them exist on the Web already, some of which are developed on GitHub as open source, preventing potential issues through collaborative development.
  • There is no need to reinvent the wheel; simply spend 20 minutes googling javascript sliders and find one that you can customise to your needs.

A couple I like using are 'caroufredsel', which is responsive and offers a few nice features (dynamically adding items, callbacks etc).

Another is 'flexslider'.

Upvotes: 1

Related Questions