0

Im trying to work out script that will change background images every 3 sec using fadeIn, fadeOut, addClass and removeClass. Is there a better way to do it using setInterval?

$("document").ready(function () {

 $("#bg").delay(3000);
 $("#bg").fadeOut(300);
 $("#bg").removeClass('bg1');
 $("#bg").addClass('bg2');
 $("#bg").fadeIn(300);

 $("#bg").delay(3000);
 $("#bg").fadeOut(300);
 $("#bg").removeClass('bg2');
 $("#bg").addClass('bg1');
 $("#bg").fadeIn(300);


});

btw. its not working properly.

HTML:

<div id="bg" class="ShowBG bg1"></div>

CSS:

#bg{
position:absolute;
width:100%;
height:70%;
background-size:cover;
background-position:center;
display:none;
}
.bg1{background-image:url("/img/index/bg1.png");}
.bg2{background-image:url("/img/index/bg2.png");}
Qriyo
  • 43
  • 6

3 Answers3

2

Your method should work just fine but it's not the best way to write it: what if your graphic designer suddenly decides to add another background image in the cycle? Your code could become pretty long pretty fast. Here's how I would do it:

var backgroundClasses = ['bg1', 'bg2']; // Store all the background classes defined in your css in an array
var $element = $('.container'); // cache the element we're going to work with
var counter = 0; // this variable will keep increasing to alter classes

setInterval(function() { // an interval
 counter++; // increase the counter
 $element.fadeOut(500, function() { // fade out the element
   $element.removeClass(backgroundClasses.join(' ')). // remove all the classes defined in the array
    addClass(backgroundClasses[counter % backgroundClasses.length]). // add a class from the classes array
    fadeIn(500); // show the element
  });
}, 3000)
.container {
  width: 100vw;
  height: 100vh;
}

.bg1 {
  background-color: red;
}

.bg2 {
  background-color: green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container bg1"></div>

The hardest part of the code is this:

$element.addClass(backgroundClasses[counter % backgroundClasses.length])

It basically adds one of the classes stored in the backgroundClasses array. Using the modulo operator (%) on the counter will basically start over every time it has reached the end of the array, counting 0, 1, 0, 1, 0, 1 if you're array is only 2 elements long. If it's 3 elements long it counts 0, 1, 2, 0, 1, 2, ... and so on. Hope that makes sense.

Jonas Grumann
  • 10,438
  • 2
  • 22
  • 40
  • any idea how to make images fade in each other ? this works like showing imgage fade to black and next is fading in from black. id like to make image fading out and fading in at the same time so it looks like they fade in each other. – Qriyo May 12 '17 at 22:05
  • Sadly this isn't possible with the current html structure, you will need to have different elements for each background slide: https://jsfiddle.net/9a6sjstb/ – Jonas Grumann May 15 '17 at 07:32
1

Edit

Just noticed OP wants fading so I added a simple CSS transition and opacity properties to both classes and #bg.

Use toggleClass(). Not sure why you used display:none so I removed it. Also I added the dimensions to html and body so your div has something to relate it's percentage lengths with.

Demo

setInterval(function() {
  $('#bg').toggleClass('bg1 bg2');
}, 3000);
html,
body {
  height: 100%;
  width: 100%
}

#bg {
  position: absolute;
  width: 100%;
  height: 70%;
  background-size: cover;
  background-position: center;
  opacity:1;
  transition:all 1s;
}

.bg1 {
  background-image: url("http://placehold.it/500x250/00f/eee?text=BG1");
  opacity:1;
  transition:all 1s;
}

.bg2 {
  background-image: url("http://placehold.it/500x250/f00/fff?text=BG2");
  opacity:1;
  transition:all 1s;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="bg" class="ShowBG bg1"></div>
Community
  • 1
  • 1
zer00ne
  • 41,936
  • 6
  • 41
  • 68
  • yee. I need fadeIn and fadeOut effects – Qriyo May 12 '17 at 13:58
  • I've accepted other answer :] I can have to add more background images later :] btw. first two changes are flat without fadeIn / fadeOut effect – Qriyo May 12 '17 at 14:08
  • @Qriyo, there's a [FOUC](https://en.wikipedia.org/wiki/Flash_of_unstyled_content) on the first transition but it still fades. With CSS transition it's smooth thereafter. With all due respect to Mr. G, that demo uses more code and you can see a gap between changes. – zer00ne May 12 '17 at 14:15
  • @Qriyo, I didn't see anything about 2+ images, if included in question, I'd adjust accordingly. I'd go with the array solution as well but with a delay between classes. – zer00ne May 12 '17 at 14:18
  • ye thats my bad :] – Qriyo May 12 '17 at 22:09
  • No worries, sir, happy coding. – zer00ne May 13 '17 at 02:28
1

Use callback of fadeOut() method (see complete parameter here) to perform class change when the animation is done. Otherwise the class will swap while the animation is still going.

There is no better way than using setInterval() if you want to do it automatically and continuously.

Here is working example:

$("document").ready(function () {
 var bg = $("#bg");
 setInterval(function() {
    // We fadeOut() the image, and when animation completes we change the class and fadeIn() right after that.
    bg.fadeOut(300, function() {
     bg.toggleClass('bg1 bg2');
     bg.fadeIn(300);
    });
 }, 1500);

});
#bg {
  position:absolute;
  width:100%;
  height:70%;
  background-size:cover;
  background-position:center;
}
.bg1 {
  background-image: url("https://www.w3schools.com/css/img_fjords.jpg");
}
.bg2 {
  background-image: url("https://www.smashingmagazine.com/wp-content/uploads/2015/06/10-dithering-opt.jpg");
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="bg" class="ShowBG bg1"></div>
Marcin Pevik
  • 163
  • 1
  • 14