Search code examples
javascripthtmlcssslideshow

How to force-reload background image in <div> using CSS and Javascript


I would like to build a very simple webpage slide show showing a new photo every few seconds using HTML, CSS and Javascript. I managed to get it running locally on my Linux box with Firefox but as soon as I run the show via my Linux Apache VPS, things break down and the photo image is not updated in Firefox or Chrome although the HTML page gets reloaded as expected. The URL for the image "./slsh.jpg" sits on my Apache server and is actually a randomly though periodically updated symbolic link to one of many photos stored there.

As you see below, I inherited an example code from the web to get the pictures displayed fullsize within the browser window using some CSS tricks within div "a". This setup seems to work fine except that I can't get that unique "URL + timestamp" approach operational with Javascript. I most likely don't know how to update that URL string of the background image as I may have screwed up my Javascript lines or the ID reference such as "a".

As soon as I use the Javascript line starting with "document.getElement..." the script seems to just crash, the HTML page is not reloaded anymore, nor is the new image displayed - except when I manually force-reload it with ctrl+shift+r in Chrome for example.

<script>
  var timestamp = new Date().getTime();
  document.getElementById("a").style.backgroundImage = "url(./slsh.jpg?t=" + timestamp + ")";
  window.setInterval('refresh()', 3000);
  function refresh() {
      location.reload();
</script>
<style>
  body, html {
      height: 100%;
      margin: 0;
  }
  .bg {
      background-image: url('./slsh.jpg');
      height: 100%; 
      background-position: center;
      background-repeat: no-repeat;
      background-size: contain;
      background-color: rgb(10,10,10);
  }
</style>
<!DOCTYPE html>
<html>
<head>
<!--- here sits my CSS code --->
<!--- here sits my javascript code --->
</head>
<body id="body">
  <div class="bg" id="a"></div>
</body>

</html>

What is wrong here? What needs to adjusted or added in order to make this photo slide show run smoothly? I saw many suggestions on the web - but my particular scenario differs somewhat as I use div with that backgroundImage solution which shows my photos the way I want it.


Solution

  • You don't have to reload the whole html page in order to change the image, in fact you can pre-cache the images if you don't, leading to a smoother slideshow. Here's an example.

    Note: Change the listOfImageUrls which I'm lazy and auto-generate to your own array of urls to different images.

    slideshow.html

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
      <meta charset="UTF-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>Slideshow</title>
      <link rel="stylesheet" href="slideshow.css">
    </head>
    
    <body>
      <script src="slideshow.js"></script>
    </body>
    
    </html>
    

    slideshow.css

    body {
      background-color: black;
      background-size: cover;
      background-attachment: fixed;
    }
    

    slidehow.js

    // How many seconds before shifting image
    const secondsBetweenSlides = 5;
    
    // An array of image urls - just generating from unsplash for now
    const listOfImageUrls = [...new Array(15)].map(() =>
      `https://source.unsplash.com/random/?food&nocache=${Math.random()}`);
    
    // Sleep for a number of ms
    const sleep = ms => new Promise(res => setTimeout(res, ms));
    
    // Run the show
    const slideShow = async () => {
      while (true) {
        let imageToShow = listOfImageUrls.shift();
        listOfImageUrls.push(imageToShow)
        document.body.style.backgroundImage = `url(${imageToShow})`;
        await sleep(secondsBetweenSlides * 1000);
      }
    }
    
    slideShow();