简体   繁体   中英

JavaScript img slider with fade

So, I have been trying to make a slideshow for my website. I have got the slideshow working fine, but then I decided to add some fading between images by changing the opacity slowly up and down before and after the image change respectively. I've read through he code over and over and although the logic in the code below is a little hard to follow, as far as I can tell it should work very smoothly. I am using a for loop to generate setTimeout statements for each individual opacity change.

//Shortcut for getElementById()
function e(eel) {
    return document.getElementById(eel);
}

//Slideshow
window.slideShow();

function slideShow(){
    var a = setTimeout(loopChange,8000);
    var b = setTimeout(function(){changeSrcTo("Other/noctis.jpg")},10000);
    var c = setTimeout(loopChange,18000);
    var d = setTimeout(function(){changeSrcTo("Other/retriever.jpg")},20000);
    var e = setTimeout(loopChange,28000);
    var f = setTimeout(function(){changeSrcTo("Other/miningop2.jpg")},30000);
    var g = setTimeout(slideShow,30000);
}
function changeSrcTo(thisSrc){
    e('dynimg').src=thisSrc;
}
function loopChange(){
    for(i=0;i<=10;i++){
        var t = setTimeout(function(){changeOpacity((1-(i*0.02)))},(i*200));
    }
    for(i=0;i<=20;i++){
        var u = setTimeout(function(){changeOpacity((0.6+(i*0.02)))},((i*200)+2000));
    }
}
function changeOpacity(oValue){
    e('dynimg').style.opacity=oValue;
    e('dynimg').style.filter="alpha("+(oValue*100)+")"; 
}

I apologise profusely for just dumping code on you guys, but I don't really know who else to ask. I hope my terrible code isn't too confusing. Essentially, it is really jumpy and is only fading a slit second before the img change and isn't fading back. Instead of the next image fading back in, it is just changing and appearing at 1.0 opacity.

1) make a div

2) set its with/height to match the dimensions of your images

3) use this

 function toggleImg(imgurl,effectDuration)
 {
     $('#DIV').animate( {opacity: 0}, effectDuration/2 , function(){
         $(this)
             .css( { 'background-image': 'url('+imgurl+')' } )
             .animate( {opacity: 1} , effectDuration/2 );
     });
 }
 //~ can't get any easier than that.



......:::::: A Big Friendly Button! ::::::......



Since you can't animate( { backgroundImage: 'img.png',opacity:1 }, 500);

We had to improvise .

Step 1. Fade out
$('#DIV').animate({opacity: 0}, fadeDuration/2 , function(){ /*on completion*/});

Step 2. Change the image
function(){ $(this).css({'background-image':'url('+imgurl+')'}) ...

Step 2. Fade in
... animate({opacity:1},fadeDuration/2); ...



~> The code ... explained

$('#div') follows the exact same logic of documentGetElementById('div')
but it allows you to use JQueries functions.

animate

  1. CSS property to animate

  2. The animations duration

  3. A function which will be called when the animation is complete.

css

'background-image' is the css property and imgurl is its value. ie '../img/hello.png'

In jquery you can call link many functions because most of them return $(this) so:

$('#mydiv').css().animate().toggle().css().animate() // ... etc ...



~> In other words

.animate( /* objects with their values */ , /* duration */ , /* callback function */ )
.css( /* objects with their values */ )



~> You can also do this if you like.

 function callMeWhenUrDone()
 {
       $('#mydiv').css( { 'background-image': 'url('+imgurl+')' } );
       $('#mydiv').animate( {opacity: 1} , effectDuration/2 );
 }

 function toggleImg(imgurl,effectDuration)
 {
     $('#mydiv').animate( {opacity: 0}, effectDuration/2 , callMeWhenUrDone );
 }
 //~ cheesy function

setTimeout is not what you need. First of all you must know that setTimeout function is not always precise. On your code the problem has to do with the one-thread, non-blocking nature of javascript. When you go into the loop of loopChange function what it really happens is:

the execution comes to the loop part. The variable i is instantiated having the value 0. The loop runs 10 times. During all this times each "setTimeout" call tells javascript "I know you can only run one thread. So, when you finish what you are doing change the opacity after i*200 milliseconds". Though, what javascript is doing is to iterate! So when the iteration ends then all these queued commands will execute.

And now we get in the asynchronous nature of the language. Exactly because all the commands will execute AFTER the iteration ends the variable i will have the value 10. So all of the setTimeout will execute:

changeOpacity((1-(10*0.02)))},(10*200)

This is why this code doesn't work. I believe that the jQuery animate proposed by TheOtherGuy is a good solution though I would consider working with css3 transitions which are much smoother. Take a look here: http://www.w3schools.com/css3/css3_transitions.asp

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM