Search code examples
javascripthtmlcssbackground-color

JavaScript Change Background Color On Scroll


I am practicing Javascript and css. I want to change my background color when scrolling down. I don't want to use library for that. I have followed this code-pen demo to learn the logic but he used jquery. I have followed w3school for scrollTop .My javascript logic works but it does not work like this demo. I think I have to target each div in order to change the background-color but don't know how.

function showScrollColorChange() {
  //let scroll = window.scrollTop() + (window.height() / 3); 

  if (document.body.scrollTop > 20 || document.documentElement.scrollTop > 30) {
    document.body.classList.add('color-violet')
  } if (document.body.scrollTop > 40 || document.documentElement.scrollTop > 40) {
    document.body.classList.add('color-green')
  } else {
    document.body.classList.add('color-orange')
  }
}

/* document.body.addEventListener('scroll', () => {
  showScrollColorChange()
}) */
window.onscroll = function () { showScrollColorChange() };
*{
  box-sizing: border-box;
}

body{
  margin: 0;
  padding: 0;
  transition: background 300ms linear, color 300ms linear;
}

.container{
  display: flex;
  justify-content: center;
  margin-top: 20px;
  padding: 50px;
  min-height: 100vh;
}

p{
  width:50%;
  font-size: 20px;
}

img {
  width:500px;
  height: 500px;
  border-radius: 5px;
}
/* colours */
.color-violet {
  background-color: #7A4EAB;
}
.color-indigo {
  background-color: #4332CF;
}
.color-blue {
  background-color: #2F8FED;
}
.color-green {
  background-color: #4DCF42;
}
.color-yellow {
  background-color: #FAEB33;
}
.color-orange {
  background-color: #F19031;
}
.color-red {
  background-color: #F2293A;
}
<div class="container">
    <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Nihil at eaque in aliquam assumenda. Officiis omnis ex
      sunt quaerat magni. Provident at nihil molestias dolores tempora voluptas laborum aspernatur sint.</p>
      <img src="https://images.unsplash.com/photo-1599736375341-51b0a848f3c7?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=800&q=60" alt="">
  </div>
  <div class="container">
    <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Nihil at eaque in aliquam assumenda. Officiis omnis ex
      sunt quaerat magni. Provident at nihil molestias dolores tempora voluptas laborum aspernatur sint.</p>
      <img src="https://images.unsplash.com/photo-1599736375341-51b0a848f3c7?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=800&q=60" alt="">
  </div>
  <div class="container">
    <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Nihil at eaque in aliquam assumenda. Officiis omnis ex
      sunt quaerat magni. Provident at nihil molestias dolores tempora voluptas laborum aspernatur sint.</p>
      <img src="https://images.unsplash.com/photo-1599736375341-51b0a848f3c7?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=800&q=60" alt="">
  </div>
  <div class="container">
    <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Nihil at eaque in aliquam assumenda. Officiis omnis ex
      sunt quaerat magni. Provident at nihil molestias dolores tempora voluptas laborum aspernatur sint.</p>
      <img src="https://images.unsplash.com/photo-1599736375341-51b0a848f3c7?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=800&q=60" alt="">
  </div>
  <div class="container">
    <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Nihil at eaque in aliquam assumenda. Officiis omnis ex
      sunt quaerat magni. Provident at nihil molestias dolores tempora voluptas laborum aspernatur sint.</p>
      <img src="https://images.unsplash.com/photo-1599736375341-51b0a848f3c7?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=800&q=60" alt="">
  </div>


Solution

  • Here is a dynamic way.

    Get all containers elements and add the position of their top to an array:

    containers = document.getElementsByClassName("container");
    var containertops = [];
    containertops.push(0);  // add for space before 1st container
    for (var i = 0; i < containers.length; i++) {
      containertops.push(containers[i].offsetTop);
    }
    

    Make an array of the colour classes in the order to be used. It is easy to change the colours and order doing this:

    // array of colours to use
    var colours = [
      "white",
      "color-violet",
      "color-indigo",
      "color-blue",
      "color-green",
      "color-yellow",
      "color-orange",
      "color-red",
    ];
    

    In scroll function, loop through the array of containers top positions. For each i in the loop, use this as an index to get a new colour from the colours array so the colour changes for every container. If there are more containers than colours, use the last colour for the rest.

    // loop through the containers and add a new colour as the containers change
      for (var i = 0; i < containertops.length; i++) {
    
        // if this container is at the top of the screen get a new colour class
        if (document.body.scrollTop >= containertops[i] || document.documentElement.scrollTop >= containertops[i]) {
          document.body.className = '';  // clear class
    
          // if we have not enough colours, use the last colour class again
          colourclass= (i>=colours.length?colours.length-1: i);
          document.body.classList.add(colours[colourclass]);
        }
      }
    

    This is the code working:

    //dynamically add all containers to array
    containers = document.getElementsByClassName("container");
    var containertops = [];
    containertops.push(0);  // add for space before 1st container
    for (var i = 0; i < containers.length; i++) {
      containertops.push(containers[i].offsetTop);
    }
    
    // array of colours to use
    var colours = [
      "white",
      "color-violet",
      "color-indigo",
      "color-blue",
      "color-green",
      "color-yellow",
      "color-orange",
      "color-red",
    ];
    
    function showScrollColorChange() {
      // loop through the containers and add a new colour as the containers change
      for (var i = 0; i < containertops.length; i++) {
      
         // if this container is at the top of the screen get a new colour class
        if (document.body.scrollTop >= containertops[i] || document.documentElement.scrollTop >= containertops[i]) {
        
          document.body.className = '';  // clear class      
         // if we have not enough colours, use the last colour class again
          colourclass= (i>=colours.length?colours.length-1: i);
          document.body.classList.add(colours[colourclass]);
        }
      }
    }
    
    
    window.onscroll = function() {
      showScrollColorChange()
    };
    * {
      box-sizing: border-box;
    }
    
    body {
      margin: 0;
      padding: 0;
      transition: background 300ms linear, color 300ms linear;
    }
    
    .container {
      display: flex;
      justify-content: center;
      margin-top: 20px;
      padding: 50px;
      min-height: 100vh;
    }
    
    p {
      width: 50%;
      font-size: 20px;
    }
    
    img {
      width: 500px;
      height: 500px;
      border-radius: 5px;
    }
    
    
    /* colours */
    
    .color-violet {
      background-color: #7A4EAB;
    }
    
    .color-indigo {
      background-color: #4332CF;
    }
    
    .color-blue {
      background-color: #2F8FED;
    }
    
    .color-green {
      background-color: #4DCF42;
    }
    
    .color-yellow {
      background-color: #FAEB33;
    }
    
    .color-orange {
      background-color: #F19031;
    }
    
    .color-red {
      background-color: #F2293A;
    }
    <div class="container">
      <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Nihil at eaque in aliquam assumenda. Officiis omnis ex sunt quaerat magni. Provident at nihil molestias dolores tempora voluptas laborum aspernatur sint.</p>
      <img src="https://images.unsplash.com/photo-1599736375341-51b0a848f3c7?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=800&q=60" alt="">
    </div>
    <div class="container">
      <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Nihil at eaque in aliquam assumenda. Officiis omnis ex sunt quaerat magni. Provident at nihil molestias dolores tempora voluptas laborum aspernatur sint.</p>
      <img src="https://images.unsplash.com/photo-1599736375341-51b0a848f3c7?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=800&q=60" alt="">
    </div>
    <div class="container">
      <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Nihil at eaque in aliquam assumenda. Officiis omnis ex sunt quaerat magni. Provident at nihil molestias dolores tempora voluptas laborum aspernatur sint.</p>
      <img src="https://images.unsplash.com/photo-1599736375341-51b0a848f3c7?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=800&q=60" alt="">
    </div>
    <div class="container">
      <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Nihil at eaque in aliquam assumenda. Officiis omnis ex sunt quaerat magni. Provident at nihil molestias dolores tempora voluptas laborum aspernatur sint.</p>
      <img src="https://images.unsplash.com/photo-1599736375341-51b0a848f3c7?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=800&q=60" alt="">
    </div>
    <div class="container">
      <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Nihil at eaque in aliquam assumenda. Officiis omnis ex sunt quaerat magni. Provident at nihil molestias dolores tempora voluptas laborum aspernatur sint.</p>
      <img src="https://images.unsplash.com/photo-1599736375341-51b0a848f3c7?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=800&q=60" alt="">
    </div>