SitePoint Sponsor

User Tag List

Results 1 to 4 of 4
  1. #1
    Community Advisor silver trophybronze trophy
    dresden_phoenix's Avatar
    Join Date
    Jun 2008
    Location
    Madison, WI
    Posts
    2,791
    Mentioned
    34 Post(s)
    Tagged
    2 Thread(s)

    fade image with javascript.

    I am trying to code a simple slider with a fade effect using .js but I am stuck;
    I just cant figure out where the error in my logic is:

    I have an array ( the list of images) and another array which I am using to cache image objects.
    the slider() function checks for and skips missing images, adds a new image to the container and calls the fade() function.
    fade() gets an image node list of the target container. the count of which should be 2: the previous image and the one that slider() added.
    fade() then decreases the opacity of the first image until it reaches 0, then it removes that image completely, waits for a set interval and calls fader() for the next image in the cache array, so the loop continues.

    any insight would be appreciated

    code here: http://raym31.home.comcast.net/fader/
    Last edited by dresden_phoenix; Feb 22, 2013 at 21:18.

  2. #2
    SitePoint Guru bronze trophy
    Join Date
    Dec 2003
    Location
    Poland
    Posts
    930
    Mentioned
    7 Post(s)
    Tagged
    0 Thread(s)
    I don't know if I follow the logic in your code but I have a working script for such a simple slider that I have written some time ago and I use it on a few sites. Maybe you'll get some inspiration from it so I'll present it here in a most simple way:

    HTML Code:
    <!DOCTYPE html>
    <html>
    <head>
    	<script type="text/javascript" src="slider.js"></script>
    </head>
    
    <body>
    	<div id="slider">
    		<img src="slider1.jpg" alt="" onload="slider.init();" />
    	</div>
    </body>
    </html>
    The idea is that the first image is defined in html while the remaining ones in js. During fade-in there will be two images in the div and as the process is finished the first (old) image will be removed from DOM - and so on. Of course, you'll have to take care of proper css so multiple images in the div appear in the same spot (posidion: relative on div, absolute on img).

    I find it best to initialize the script with the inline onload handler since it is most reliable - there's no way, AFAIK, to replicate the same behaviour in the "proper" modern way of attaching event after DOM has loaded. If your eyes hurt because of that you can always run slider.init() at the end of the page or with some DOM onload handler.

    Now javascript, I've added comments so all explanation is in the code:

    Code JavaScript:
    var slider = {
    	freq: 18,  // time between each frame in milliseconds
    	fadeStep: 2,  // amount of opacity to increase at each frame (until it reaches 100)
    	bewtweenFades: 3000,  // time to wait between slider changes
     
    	// here go slider files except the first one, which is defined in html
    	imgFiles: [
    		'slider2.jpg',
    		'slider3.jpg'
    	],
    	current: 0,  // index number of currently visible slider
    	imgs: [],  // here we will load image elements of all sliders
     
    	init: function() {
    		slider.imgArea = document.getElementById('slider');
     
    		// load the first slider <img> into imgs (from html DOM)
    		// the 'loaded' property is used later on to prevent from displaying an
    		// image that has not been fully downloaded 
    		var img = slider.imgArea.getElementsByTagName('img')[0];
    		img.loaded = true;
    		slider.imgs.push(img);
     
    		// create remaining <img> elements and load into imgs
    		for (var i=0; i<slider.imgFiles.length; i++) {
    			img = document.createElement('img');
    			img.src = slider.imgFiles[i];
    			img.onload = function() {
    				this.loaded = true;
    			}
    			slider.imgs.push(img);
    		}
     
    		setTimeout(slider.fadeNext, slider.bewtweenFades);
    	},
     
    	/* initialize fade transition into the next image */
    	fadeNext: function() {
    		slider.current++;
     
    		if (slider.current >= slider.imgs.length) {
    			// reached the end of sequence - start from beginning
    			slider.current = 0;
    		}
     
    		if (!slider.imgs[slider.current].loaded) {
    			// give up if image is not loaded and try again in a second
    			slider.current--;
    			setTimeout(slider.fadeNext, 1000);
    			return;
    		}
     
    		// add the next image to DOM just after currently visible <img>
    		// initially at opacity 0
    		var img = slider.imgs[slider.current];
    		slider.setOpacity(img, 0);
     
    		slider.imgArea.appendChild(img);
     
    		slider.opacity = 0;  // internal opacity counter (doesn't affect display)
    		slider.currentImg = img;
    		setTimeout(slider.fadeIn, slider.freq);
    	},
     
    	/* fade in <img> */
    	fadeIn: function() {
    		slider.opacity += slider.fadeStep;
    		if (slider.opacity > 100) {
    			slider.opacity = 100;
    		}
     
    		slider.setOpacity(slider.currentImg, slider.opacity);
     
    		if (slider.opacity < 100) {
    			// continue fading
    			setTimeout(slider.fadeIn, slider.freq);
    		} else {
    			// fading finished - new <img> is fully visible
    			// so let's remove old <img> from DOM
    			var firstImg = slider.imgArea.getElementsByTagName('img')[0];
    			slider.imgArea.removeChild(firstImg);
    			setTimeout(slider.fadeNext, slider.bewtweenFades);
    		}
    	},
     
    	/* cross-browser set opacity to element */
    	setOpacity: function(elem, op) {
    		op = Math.round(op);
    		elem.style.opacity = op/100;
    		elem.style.filter = "alpha(opacity=" + op + ")";
    	}
    }

  3. #3
    Gre aus'm Pott gold trophysilver trophybronze trophy
    Pullo's Avatar
    Join Date
    Jun 2007
    Location
    Germany
    Posts
    5,889
    Mentioned
    208 Post(s)
    Tagged
    12 Thread(s)
    Hi dresden_phoenix,

    The problem in your code is in the following block:

    Code JavaScript:
    if (IMGcahe[s] !='skip'){
      if(IMGcahe[s].complete){
        fstep=25;
        document.getElementById(targ).appendChild(IMGcahe[s]);
        fade(fstep,fstep,to,s,targ);
      }
    }  else {
      slider(targ,s+1,to)
    }

    IMGcahe[s] is never set to "skip", so only the inner if statement executes, the else block never gets called.

    If you move the else block up one level, the images start cycling, although the blank images aren't skipped and the captions appear to be quite random, so maybe this isn't how things are meant to be.

    Code JavaScript:
    if (IMGcahe[s] !='skip'){
      if(IMGcahe[s].complete){
        fstep=25;
        document.getElementById(targ).appendChild(IMGcahe[s]);
        fade(fstep,fstep,to,s,targ);
      } else {
        slider(targ,s+1,to)
      }
    }

    Nonetheless, I hope this helps you somewhat.

    Edit: Oops, beaten to it by Lemon Juice

  4. #4
    Community Advisor silver trophybronze trophy
    dresden_phoenix's Avatar
    Join Date
    Jun 2008
    Location
    Madison, WI
    Posts
    2,791
    Mentioned
    34 Post(s)
    Tagged
    2 Thread(s)
    thank guys.

    LJ has given me something else to study.

    It turns out that my onError event was not firing (syntax error, how ironic), so Pullo was kinda-right; moving up the else{} actually would have made the slide switch prematurely. Once I fixed the syntax on my OnErr everything started to work. Thanks again.


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •