Pregunta

I'm trying to create image slider, which can change the body background of my website.

I found out, that changing the background directly on the body wasn't that good, so I looked for another solution.

Then I found this: jQuery Animated Background Images Fade in Out

I then changed it a bit, so instead of using img it uses a div with a background image. It works very fine, but there is something I can't figure out.

The problem is now, that when the transition occurs between two of the images, the body background is briefly shown, which I do not want to.

UPDATE

The fade do now work almost perfect. The problem now that if you're leaving the window (by minimizing or changing tab) when the transition takes place, the effect will mess up.

The other "problem" is to do the same effect, when click at the buttons. And also, when click on button 1 (Start Slider Again) the 'slider' should be restarting from the beginning and not just from where it stopped.


Here's my code so far:

jQuery:

$(window).load(function() {
    $('#slider div.bgfade').hide();
    $('#slider div.bgfade').first().show();
    function anim() {
        $("#slider div.bgfade").first().appendTo('#slider').fadeIn(1500, function() {
            $("#slider div").first().fadeOut(1500);
        });

        $set = setTimeout(anim, 3000);
    }
    anim();

    $('span').click(function() {
        $('#slider div.bgfade').fadeOut(500);
        var count = $(this).index();
        clearTimeout($set);
        if(count == 0) {
            $('#button-images div').fadeOut(500);
            anim();
        }
        else if(count == 1) {
           $('#button-images div').fadeOut(1500);
           $('#button-images div.image1').fadeIn(1500);
        }
        else if(count == 2) {
           $('#button-images div').fadeOut(1500);
           $('#button-images div.image2').fadeIn(1500);
        }
        else if(count == 3) {
           $('#button-images div').fadeOut(1500);
           $('#button-images div.image3').fadeIn(1500);
        }
   });
});

HTML:

<span>Start Slider again</span>
<span>Button 2</span>
<span>Button 3</span>
<span>Button 4</span>

<div id="slider">
    <div class="bgfade" style="background: red;"></div>
    <div class="bgfade" style="background: blue;"></div>
    <div class="bgfade" style="background: orange;"></div>
</div>
<div id="button-images">
    <div class="image1" style="background: green"></div>
    <div class="image2" style="background: yellow"></div>
    <div class="image3" style="background: pink"></div>
</div>

CSS:

body {
    background: #333;
}

span {
    display: inline-block;
    height: 30px;
    line-height: 30px;
    text-align: center;
    padding: 0 10px;
    background: #FFF;
    cursor: pointer;
}

#slider, #button-images {
    position:fixed;
    z-index:-1; 
    top:0; 
    left:0;
}
#slider div.bgfade, #button-images div {
    position:fixed;
    top:0;
    display:none;
    width:100%;
    height:100%;
    z-index:-1;
    background-repeat: no-repeat !important;
    background-position: center !important;
    background-attachment: fixed !important;
    background-size: cover !important;
}

Here's a Fiddle Demo

..and why do it start with the second image (the orange one)?

Someone who please can help me? :)

¿Fue útil?

Solución

Your problem is that both slides are changing opacity at the same time and there comes a brief moment when you can see through both of them, hence the body background becomes visible.

Try changing

$("#slider div.bgfade").first().appendTo('#slider').fadeOut(500);
$("#slider div").first().fadeIn(500);

part with this part

 var fadeout = $("#slider div.bgfade").first().appendTo('#slider');
 $("#slider div").first().fadeIn(500, function(){
     fadeout.fadeOut(500);
 });

It will fade in the next slide before fading out the current slide so the next slide will be already visible underneath the current fading slide and you'll see next slide instead of body background.

update (mostly changed code to make buttons function)

JS

$(window).load(function () {

   //just caching selector results
   var slider = $('#slider'),
      slides = $('.bgfade', slider),
      btnsCntnr = $('#sliderbuttons'),
      set;

   //assign each slide an id, and for each slide, insert a button for switching to it.
   slides.each(function (i) {
      var slideid = 'slide' + i;
      $(this).attr('id', slideid);

      //dynamically create "switch to Slide N" button
      btnsCntnr.append($('<span />', {
         id: slideid + 'btn',
         'class': 'sliderbtn',
         'data-slide': slideid /*id of the slide this button switches to*/
      }).html('Slide ' + (i + 1)));
   });

   //fix for "why do it start with the second image (the orange one)?"
   slides.hide().first().show();

   function anim(slideid) {

      var first = $('.bgfade', slider).first();

      if (first.attr('id') == slideid) {
         //slide is currently visible, so no transition required
         loopAnim();
         return;
      }

      //next slide is the slide with specified slideid, otherwise 2nd slide (the one after the visible one)
      var next = typeof slideid === 'undefined' ? $(".bgfade:nth-child(2)", slider) : $('#' + slideid, slider),
      //current slide is all slides before next slide
      current = next.prevAll().appendTo(slider);

      next.stop().fadeIn(500, function () {
         //only fadeout visible slides
         current.filter(function () {
            return $(this).is(':visible');
         }).stop().fadeOut(500);
      });

      //set next transition
      loopAnim();
   }

   function loopAnim() {
      set = window.setTimeout(anim, 5000);
   }

   function stopAnim() {
      window.clearTimeout(set);
   }

   function switchSlide(slideid) {
      stopAnim();
      anim(slideid);
   }

   $('.sliderbtn').click(function () {
      switchSlide($(this).data('slide'));
   });

   //start slider
   loopAnim();

});

HTML

<div id="sliderbuttons"></div>

<div id="slider">
   <div class="bgfade" style="background: url(large11.jpg);"></div>
   <div class="bgfade" style="background: url(large12.jpg);"></div>
   <div class="bgfade" style="background: url(large13.jpg);"></div>
</div>

Otros consejos

Take a look at this: http://jsfiddle.net/techsin/Dk2uT/1/

To make it for buttons just call changeBg function..

var imgs = $("div[class^='img']"), ln = imgs.length;
imgs.eq(ln-1).show();

setInterval(changeBg,800);

var i=0;
function changeBg() {
    imgs.css('z-index','-1')
    .eq(i).css('z-index','1').fadeIn(function(){
       imgs.not(imgs.eq(i)).hide(); 
        i = ++i % ln;
    });
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top