【问题标题】:JavaScript Change Background Color On ScrollJavaScript 在滚动时更改背景颜色
【发布时间】:2021-01-01 20:07:16
【问题描述】:

我正在练习 Javascript 和 css。我想在向下滚动时更改背景颜色。我不想为此使用图书馆。我已经按照这个code-pen 演示来学习逻辑,但他使用的是 jquery。我已关注 w3school 的 scrollTop 。我的 javascript 逻辑有效,但它不像 demo 那样工作。我想我必须针对每个 div 来更改背景颜色,但不知道如何。

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>

【问题讨论】:

    标签: javascript html css background-color


    【解决方案1】:

    我看到了 2 个解决方案:

    1. 您只需将类添加到您的正文中,因此随着时间的推移,正文将包含每个类,并且其颜色将设置为最后添加的类,因此您还应该使用 classList.remove('className') 删除每个未使用的类;
    2. 只需使用 document.body.style.background = '#FFFFFF' 更改正文背景,并为更改的每种颜色添加 cmets 以避免混淆。

    【讨论】:

      【解决方案2】:

      IntersectionObserver 非常方便。您只需观察每个容器。

      我为元素添加了一个名为_class 的自定义属性。如果元素进入/离开视口,它包含应该添加/删除的类的名称。

      观察者在主线程之外运行,因此它的性能更高。

      要查看它的工作原理,您需要打开全屏模式。阈值设置为 0.9 意味着 90% 的 div 需要在类添加到 body 之前可见。

      let containers = document.querySelectorAll(".container")
      
      let observer = new IntersectionObserver((entries) => {
         entries.forEach((entry, i) => {
            let color = entry.target.attributes._class.nodeValue;
            if(entry.isIntersecting) {
              document.body.className = "";
               document.body.classList.add(color);
            }
         })
      }, {threshold: 0.9})
      
      containers.forEach(container => {
         observer.observe(container);
      })
      *{
        box-sizing: border-box;
        padding: 0;
        margin: 0;
      }
      
      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="color-violet" 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="color-indigo" 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="color-blue" 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="color-green" 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="color-yellow" 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>

      【讨论】:

        【解决方案3】:

        这是一种动态方式。

        获取所有容器元素并将其顶部的位置添加到数组中:

        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",
        ];
        

        在滚动函数中,循环遍历容器顶部位置的数组。对于循环中的每个i,将其用作索引以从颜色数组中获取新颜色,以便每个容器的颜色都发生变化。如果容器多于颜色,则使用最后一种颜色。

        // 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]);
            }
          }
        

        这是代码工作:

        //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>

        【讨论】:

        • 还有其他方法可以编写此代码吗?我不明白你做了什么,但这是我正在寻找的答案。我是初级程序员?。
        • @krisna 好的,你明白什么?你知道数组和循环吗?
        • var containertops = []; containertops.push(0); // add for space before 1st container for (var i = 0; i &lt; containers.length; i++) { containertops.push(containers[i].offsetTop); } 为什么要推两次容器顶部?
        • 我也不明白showScrollColorChange()。我知道数组和循环
        • @krisna 然后在滚动函数中,循环从 0 开始遍历容器的每个位置。它将屏幕顶部与容器进行比较,直到在屏幕上找到一个。假设容器 3 在屏幕上。当它找到它时,循环索引为 3。这用作颜色数组的键,以获取数组中那个位置的颜色,即蓝色。这个类被添加到容器中。有代码得到colourclass,你可以忽略它:)只有当你的颜色少于容器时才需要。您可以改用i
        猜你喜欢
        • 1970-01-01
        • 2013-09-07
        • 1970-01-01
        • 2017-04-23
        • 1970-01-01
        • 1970-01-01
        • 2014-06-30
        • 2015-12-16
        相关资源
        最近更新 更多