Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Preloading images on safari for background image change [duplicate]

I have a background that changes every 12seconds. In Chrome, Firefox and Opera the background change is works fine, but in Safari the browser always loads the image again and that is noticed by a flickering on every image change on the first cycle. Any ideas on how can I solve this problem.

This is how I'm handling the background change:

var img2 = new Image();
var img3 = new Image();
img2.src="/img/bg2.png";
img3.src="/img/bg3.png";
Meteor.setInterval(function(){
    let elem = $(".header-2");
    if(elem.hasClass("bg1")){
        elem.removeClass("bg1");
        elem.addClass("bg2");
        let src = 'url('+img2.src.replace(location.origin,'')+')';
        elem.css("background-image", src);
    }
    else if(elem.hasClass("bg2")){
        elem.removeClass("bg2");
        elem.addClass("bg3");
        let src = 'url('+img3.src.replace(location.origin,'')+')';
        elem.css("background-image", src);
    }
    else{
        elem.removeClass("bg3");
        elem.addClass("bg1");
    }
}, 12*1000)

The css classes:

.header-2.bg1 {
    background-image: url('/img/bg1.png');
}
.header-2.bg2 {

}
.header-2.bg3 {

}
like image 989
Miguel Morujão Avatar asked Mar 13 '17 11:03

Miguel Morujão


2 Answers

Changing the background after an onload event on the image should ensure the image is completely loaded before updating anything on the page.

This approach adds the event and keeps the background changes in JS.

var bgs = ['http://3.bp.blogspot.com/_EqZzf-l7OCg/TNmdtcyGBZI/AAAAAAAAAD8/KD5Y23c24go/s1600/homer-simpson-1280x1024.jpg', 'http://cdn.thedailybeast.com/content/dailybeast/articles/2015/03/31/neil-degrasse-tyson-defends-scientology-and-the-bush-administration-s-science-record/jcr:content/image.img.2000.jpg/1432067001553.cached.jpg','http://www.mrwallpaper.com/wallpapers/Huge-Bear.jpg'],
  count = 1,
  header2 = document.getElementsByClassName('header-2')[0];

setInterval(function() {
  var img2 = new Image(),
    url = bgs[count];
  img2.onload = function() {
    header2.style.backgroundImage = 'url(' + url + ')';
  }
  img2.src = url;
  (count < (bgs.length - 1)) ? count++ : count = 0;
},1000)
body {
  margin: 0;
}
.header-2 {
  background-position: top center;
  background-repeat: no-repeat;
  background-size: cover;
  height: 100vh;
  margin: 0;
  background-image: url('http://3.bp.blogspot.com/_EqZzf-l7OCg/TNmdtcyGBZI/AAAAAAAAAD8/KD5Y23c24go/s1600/homer-simpson-1280x1024.jpg');
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<header class="header-2"></header>

You can also use the same method with your code where you're using CSS to control parts of it. Here I just set a data-bg attribute in your interval, then control the background-image (and whatever else) via CSS using the data selector

var bgs = ['http://3.bp.blogspot.com/_EqZzf-l7OCg/TNmdtcyGBZI/AAAAAAAAAD8/KD5Y23c24go/s1600/homer-simpson-1280x1024.jpg', 'http://cdn.thedailybeast.com/content/dailybeast/articles/2015/03/31/neil-degrasse-tyson-defends-scientology-and-the-bush-administration-s-science-record/jcr:content/image.img.2000.jpg/1432067001553.cached.jpg', 'http://www.mrwallpaper.com/wallpapers/Huge-Bear.jpg'],
  count = 0,
  header2 = document.getElementsByClassName('header-2')[0];

setInterval(function() {

  var img2 = new Image(),
      url = bgs[count];

  img2.onload = function() {
    header2.setAttribute('data-bg', count);
  }

  img2.src = url;

  (count < (bgs.length - 1)) ? count++ : count = 0;
}, 1000)
body {
  margin: 0;
}
.header-2 {
  background-position: top center;
  background-repeat: no-repeat;
  background-size: cover;
  height: 100vh;
  margin: 0;
  background-image: url('http://3.bp.blogspot.com/_EqZzf-l7OCg/TNmdtcyGBZI/AAAAAAAAAD8/KD5Y23c24go/s1600/homer-simpson-1280x1024.jpg');
}
.header-2[data-bg="1"] {
  background-image: url('http://cdn.thedailybeast.com/content/dailybeast/articles/2015/03/31/neil-degrasse-tyson-defends-scientology-and-the-bush-administration-s-science-record/jcr:content/image.img.2000.jpg/1432067001553.cached.jpg');
}
.header-2[data-bg="2"] {
  background-image: url('http://www.mrwallpaper.com/wallpapers/Huge-Bear.jpg');
}
<header class="header-2" ></header>
like image 171
Michael Coker Avatar answered Sep 24 '22 03:09

Michael Coker


this is possibly due to images not loading properly before the script is being executed by calling the function onload() will do the trick.

like image 40
captainchhala Avatar answered Sep 25 '22 03:09

captainchhala