如果在滚动时可见div,则设置并更改正文的背景颜色

时间:2018-01-12 16:18:26

标签: javascript jquery html css scroll

我尝试使用jQuery更改background-color body,当滚动时可以看到特定div(在我的示例中为红色)。如果div不可见,则背景颜色应该随动画再次更改。我试过跟随,但它不起作用。这里还有一个codepen代码段:https://codepen.io/STWebtastic/pen/qpKdeo



$(window).scroll(function(){
  $('.m-box--red').each(function(){
    if(isScrolledIntoView($(this)) ){
      $("html body").animate({ backgroundColor: "red" }, 300);
  console.log('hello');
    }
    else{
      $("html body").animate({ backgroundColor: "white" }, 300);
  console.log('hello');
    }
  });
});

function isScrolledIntoView(elem){
    var $elem = $(elem);
    var $window = $(window);

    var docViewTop = $window.scrollTop();
    var docViewBottom = docViewTop + $window.height();

    var elemTop = $elem.offset().top;
    var elemBottom = elemTop + $elem.height();

    return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop));
}
&#13;
body {
  box-sizing: border-box;
  margin: 0;
}

.m-box {
  display: flex;
  align-items: center;
  padding: 10px;
  background-color: #75989F;
  margin-bottom: 100px;
  cursor: pointer;
  color: white;
  transition: background-color 0.3s;
  height: 300px;
}

.m-box--second {
  background-color: #68808E;
}

.m-box--third {
  background-color: #CDC2AA;
  color: gray;
}

.m-box--red {
  background-color: #D29B8E;
  border: 1px solid lightgray;
}

.m-box__text {
  font-size: 45px;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="m-box">
  <p class="m-box__text">Quisque velit nisi, pretium ut lacinia in, elementum id enim.</p>
</div>

<div class="m-box m-box--second">
  <p class="m-box__text">Curabitur non nulla sit amet nisl tempus convallis quis ac lectus. Praesent sapien massa, convallis a pellentesque nec, egestas non nisi. Nulla porttitor accumsan tincidunt. Sed porttitor lectus nibh. Praesent sapien massa, convallis a pellentesque
    nec, egestas non nisi.</p>
</div>

<div class="m-box m-box--red">
  <p class="m-box__text">Mauris blandit aliquet elit, eget tincidunt nibh pulvinar a. Donec sollicitudin molestie malesuada. Praesent sapien massa, convallis a pellentesque nec, egestas non nisi.</p>
</div>

<div class="m-box m-box--third">
  <p class="m-box__text">Mauris blandit aliquet elit, eget tincidunt nibh pulvinar a. Donec sollicitudin molestie malesuada. Praesent sapien massa, convallis a pellentesque nec, egestas non nisi.</p>
</div>

<div class="m-box">
  <p class="m-box__text">Quisque velit nisi, pretium ut lacinia in, elementum id enim.</p>
</div>
&#13;
&#13;
&#13;

5 个答案:

答案 0 :(得分:2)

可能有一个问题:

jQuery animate backgroundColor

另一个问题是你遍历所有的div,所以身体背景将获得循环的最后一项中的条件的颜色。所以在你的情况下,总是白色。

所以我认为你可以在background属性上添加一个转换,只测试红色div。

工作代码:

https://codepen.io/Alvan/pen/rpKLjY?editors=1111

$(window).scroll(function(){
  $('.m-box--red').each(function(){
    if(isScrolledIntoView($(this)) ){
      $("body").addClass('red');
    }
    else{
      $("body").removeClass('red');
    }
  });
});

function isScrolledIntoView(elem){
    var $elem = $(elem);
    var $window = $(window);

    var docViewTop = $window.scrollTop();
    var docViewBottom = docViewTop + $window.height();

    var elemTop = $elem.offset().top;
    var elemBottom = elemTop + $elem.height();

    return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop));
}
body {
  box-sizing: border-box;
  margin: 0;
  background: white;
  transition: background .3s;
}

body.red {
  background: red;
}

.m-box {
  display: flex;
  align-items: center;
  padding: 10px; 
  background-color: #75989F;
  margin-bottom: 100px;
  cursor: pointer;
  color: white;
  transition: background-color 0.3s;
  height: 150px;
}
.m-box:hover {
    background-color: lighten(#75989F, 10);
  }
  
.m-box--second {
    background-color: #68808E;
}
.m-box--second hover {
    background-color: lighten(#68808E, 10);
}

  
.m-box--third {
    background-color: #CDC2AA;
    color: gray;
}

.m-box--third:hover {
   background-color: lighten(#CDC2AA, 10);
}
  
.m-box--red {
    background-color: #D29B8E;
    border: 1px solid lightgray;
}

.m-box--red :hover {
    background-color: lighten(#D29B8E, 10);
}
  
  
.m-box__text {
  font-size: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="m-box">
  <p class="m-box__text">Quisque velit nisi, pretium ut lacinia in, elementum id enim.</p>
</div>

<div class="m-box m-box--second">
  <p class="m-box__text">Curabitur non nulla sit amet nisl tempus convallis quis ac lectus. Praesent sapien massa, convallis a pellentesque nec, egestas non nisi. Nulla porttitor accumsan tincidunt. Sed porttitor lectus nibh. Praesent sapien massa, convallis a pellentesque nec, egestas non nisi.</p>
</div>

<div class="m-box m-box--red">
  <p class="m-box__text">Mauris blandit aliquet elit, eget tincidunt nibh pulvinar a. Donec sollicitudin molestie malesuada. Praesent sapien massa, convallis a pellentesque nec, egestas non nisi.</p>
</div>

<div class="m-box m-box--third">
  <p class="m-box__text">Mauris blandit aliquet elit, eget tincidunt nibh pulvinar a. Donec sollicitudin molestie malesuada. Praesent sapien massa, convallis a pellentesque nec, egestas non nisi.</p>
</div>

<div class="m-box">
  <p class="m-box__text">Quisque velit nisi, pretium ut lacinia in, elementum id enim.</p>
</div>

如果您希望功能在屏幕顶部出现时工作,直到屏幕底部消失,请更改条件 function isScrolledIntoView

if(elemTop <= docViewBottom && elemBottom >= docViewTop) {
    return true;
}

$(window).scroll(function(){
  $('.m-box--red').each(function(){
    if(isScrolledIntoView($(this)) ){
      $("body").addClass('red');
    }
    else{
      $("body").removeClass('red');
    }
  });
});

function isScrolledIntoView(elem){
    var $elem = $(elem);
    var $window = $(window);

    var docViewTop = $window.scrollTop();
    var docViewBottom = docViewTop + $window.height();
  
    var elemTop = $elem.offset().top;
    var elemBottom = elemTop + $elem.height();
  
    if(elemTop <= docViewBottom && elemBottom >= docViewTop) {
      return true;
    }
}
body {
  box-sizing: border-box;
  margin: 0;
  background: white;
  transition: background .3s;
}

body.red {
  background: red;
}

.m-box {
  display: flex;
  align-items: center;
  padding: 10px; 
  background-color: #75989F;
  margin-bottom: 100px;
  cursor: pointer;
  color: white;
  transition: background-color 0.3s;
  height: 150px;
}
.m-box:hover {
    background-color: lighten(#75989F, 10);
  }
  
.m-box--second {
    background-color: #68808E;
}
.m-box--second hover {
    background-color: lighten(#68808E, 10);
}

  
.m-box--third {
    background-color: #CDC2AA;
    color: gray;
}

.m-box--third:hover {
   background-color: lighten(#CDC2AA, 10);
}
  
.m-box--red {
    background-color: #D29B8E;
    border: 1px solid lightgray;
}

.m-box--red :hover {
    background-color: lighten(#D29B8E, 10);
}
  
  
.m-box__text {
  font-size: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="m-box">
  <p class="m-box__text">Quisque velit nisi, pretium ut lacinia in, elementum id enim.</p>
</div>

<div class="m-box m-box--second">
  <p class="m-box__text">Curabitur non nulla sit amet nisl tempus convallis quis ac lectus. Praesent sapien massa, convallis a pellentesque nec, egestas non nisi. Nulla porttitor accumsan tincidunt. Sed porttitor lectus nibh. Praesent sapien massa, convallis a pellentesque nec, egestas non nisi.</p>
</div>

<div class="m-box m-box--red">
  <p class="m-box__text">Mauris blandit aliquet elit, eget tincidunt nibh pulvinar a. Donec sollicitudin molestie malesuada. Praesent sapien massa, convallis a pellentesque nec, egestas non nisi.</p>
</div>

<div class="m-box m-box--third">
  <p class="m-box__text">Mauris blandit aliquet elit, eget tincidunt nibh pulvinar a. Donec sollicitudin molestie malesuada. Praesent sapien massa, convallis a pellentesque nec, egestas non nisi.</p>
</div>

<div class="m-box">
  <p class="m-box__text">Quisque velit nisi, pretium ut lacinia in, elementum id enim.</p>
</div>

答案 1 :(得分:1)

您应该使用jQuery的.is:visible选择器来执行此操作:

const $scrollTarget = $(".m-box");
const $body = $("body");
const $window = $(window);

$window.on("scroll", function() {
    return $scrollTarget.is(":visible") ? $body.addClass("element-visible-class") : $body.removeClass("element-visible-class");
});

element-visible-class是您希望在元素可见时应用的类时。

答案 2 :(得分:1)

我对您的代码进行了一些更改,但我认为这是您正在寻找的解决方案:

&#13;
&#13;
$(window).scroll(function() {
   var hT = $('.m-box--red').offset().top,
       hH = $('.m-box--red').outerHeight(),       
       wH = $(window).height(),
       wS = $(this).scrollTop();  
   if (wS >= (hT+hH) || wS < (hT+hH-wH)){      
       $("body").css("background-color", "white");
   }   
   else
   if (wS > (hT+hH-wH))
   {
       $("body").css("background-color", "red");
   }   
});
&#13;
body {
  box-sizing: border-box;
  margin: 0;
  transition: background-color .5s;
}

.m-box {
  display: flex;
  align-items: center;
  padding: 10px;
  background-color: #75989F;
  margin-bottom: 100px;
  cursor: pointer;
  color: white;
  transition: background-color 0.3s;
  height: 300px;
}
.m-box:hover {
  background-color: #93aeb4;
}
.m-box--second {
  background-color: #68808E;
}
.m-box--second:hover {
  background-color: #8499a5;
}
.m-box--third {
  background-color: #CDC2AA;
  color: gray;
}
.m-box--third:hover {
  background-color: #e0d9ca;
}
.m-box--red {
  background-color: #D29B8E;
  border: 1px solid lightgray;
}
.m-box--red:hover {
  background-color: #e1bbb2;
}
.m-box__text {
  font-size: 45px;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="m-box">
  <p class="m-box__text">Quisque velit nisi, pretium ut lacinia in, elementum id enim.</p>
</div>

<div class="m-box m-box--second">
  <p class="m-box__text">Curabitur non nulla sit amet nisl tempus convallis quis ac lectus. Praesent sapien massa, convallis a pellentesque nec, egestas non nisi. Nulla porttitor accumsan tincidunt. Sed porttitor lectus nibh. Praesent sapien massa, convallis a pellentesque nec, egestas non nisi.</p>
</div>

<div class="m-box m-box--red">
  <p class="m-box__text">Mauris blandit aliquet elit, eget tincidunt nibh pulvinar a. Donec sollicitudin molestie malesuada. Praesent sapien massa, convallis a pellentesque nec, egestas non nisi.</p>
</div>

<div class="m-box m-box--third">
  <p class="m-box__text">Mauris blandit aliquet elit, eget tincidunt nibh pulvinar a. Donec sollicitudin molestie malesuada. Praesent sapien massa, convallis a pellentesque nec, egestas non nisi.</p>
</div>

<div class="m-box">
  <p class="m-box__text">Quisque velit nisi, pretium ut lacinia in, elementum id enim.</p>
</div>
&#13;
&#13;
&#13;

你只需要添加

transition: background-color .5s;

到你的css身上。

答案 3 :(得分:0)

根据jquery doc(http://api.jquery.com/animate/):

  

除非如下所述,否则应将所有动画属性设置为单个数值。大多数非数字属性无法使用基本jQuery功能进行动画处理(例如,宽度,高度或左边可以设置动画,但背景颜色不能,除非使用jQuery.Color插件)。

如果您不想使用此插件,可以通过填写css并在需要时为您的身体添加课程来实现此目的

&#13;
&#13;
$(window).scroll(function(){
  $('.m-box--red').each(function(){
  // change the selector cause you only need this on m-box--red
 $("html body").toggleClass("red",isScrolledIntoView($(this)));
 // check if the condition is true then add class red, else remove it
  });
});

function isScrolledIntoView(elem){
    var $elem = $(elem);
    var $window = $(window);

    var docViewTop = $window.scrollTop();
 // also chnage this
    var docViewBottom = docViewTop + $("body").height();

    var elemTop = $elem.offset().top;
    var elemBottom = elemTop + $elem.height();

    return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop));
}
&#13;
body {
  box-sizing: border-box;
  margin: 0;
    transition: background-color 0.3s;

}

body.red{
  background-color:red;
}

.m-box {
  display: flex;
  align-items: center;
  padding: 10px;
  background-color: #75989F;
  margin-bottom: 100px;
  cursor: pointer;
  color: white;
  transition: background-color 0.3s;
  height: 300px;
}

.m-box--second {
  background-color: #68808E;
}

.m-box--third {
  background-color: #CDC2AA;
  color: gray;
}

.m-box--red {
  background-color: #D29B8E;
  border: 1px solid lightgray;
}

.m-box__text {
  font-size: 45px;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="m-box">
  <p class="m-box__text">Quisque velit nisi, pretium ut lacinia in, elementum id enim.</p>
</div>

<div class="m-box m-box--second">
  <p class="m-box__text">Curabitur non nulla sit amet nisl tempus convallis quis ac lectus. Praesent sapien massa, convallis a pellentesque nec, egestas non nisi. Nulla porttitor accumsan tincidunt. Sed porttitor lectus nibh. Praesent sapien massa, convallis a pellentesque
    nec, egestas non nisi.</p>
</div>

<div class="m-box m-box--red">
  <p class="m-box__text">Mauris blandit aliquet elit, eget tincidunt nibh pulvinar a. Donec sollicitudin molestie malesuada. Praesent sapien massa, convallis a pellentesque nec, egestas non nisi.</p>
</div>

<div class="m-box m-box--third">
  <p class="m-box__text">Mauris blandit aliquet elit, eget tincidunt nibh pulvinar a. Donec sollicitudin molestie malesuada. Praesent sapien massa, convallis a pellentesque nec, egestas non nisi.</p>
</div>

<div class="m-box">
  <p class="m-box__text">Quisque velit nisi, pretium ut lacinia in, elementum id enim.</p>
</div>
&#13;
&#13;
&#13;

答案 4 :(得分:0)

我建议进行一些更改以更好地优化您的代码(并同时修复它!):

  1. 让css为您设置背景颜色动画,因为这就是css if for。
  2. 将您当前正在进行的大部分处理置于滚动事件处理程序 之外,以最大限度地减少需要对该事件执行的操作。这样可以防止口吃,或“jank”。
  3. 第一个可以通过简单地添加到你的css来完成:

    body {
      transition: background-color .3s;
    }
    

    然后将您的javascript从使用animate() jquery函数更改为简单地更改css属性,如下所示:

    $('body').css('background-color','red');
    

    然后,css过渡属性将原生为您处理颜色过渡。事实上,更好的方法是让javascript简单地添加/删除一个类,让css处理该类对样式的意义。然后,您可以使用css来控制应用于body标记的这种特殊状态的样式 - 这是您的样式应该在哪里。

    以下是我对您的代码进行重写以实现这些改进(您需要将代码段视为全屏才能使效果正常工作):

    (function(){
    
      var $window = $(window);
      var $elem = $('.m-box--red');
      var elemTop = $elem.offset().top;
      var elemBottom = elemTop + $elem.height();
    
      $(window).scroll(function(){
    
        if( isScrolledIntoView( $elem ))
           $('body').addClass('js-active');
        else
           $('body').removeClass('js-active');
    
      });
    
      function isScrolledIntoView($elem){
    
          var docViewTop = $window.scrollTop();
          var docViewBottom = docViewTop + $window.height();
    
          return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop));
        }
    
    })();
    body {
      box-sizing: border-box;
      margin: 0;
      transition: background-color .3s;
    }
    body.js-active {
      background-color: red;
    }
    
    .m-box {
      display: flex;
      align-items: center;
      padding: 10px;
      background-color: #75989F;
      margin-bottom: 100px;
      cursor: pointer;
      color: white;
      transition: background-color 0.3s;
      height: 300px;
    }
    .m-box:hover {
      background-color: #93aeb4;
    }
    .m-box--second {
      background-color: #68808E;
    }
    .m-box--second:hover {
      background-color: #8499a5;
    }
    .m-box--third {
      background-color: #CDC2AA;
      color: gray;
    }
    .m-box--third:hover {
      background-color: #e0d9ca;
    }
    .m-box--red {
      background-color: #D29B8E;
      border: 1px solid lightgray;
    }
    .m-box--red:hover {
      background-color: #e1bbb2;
    }
    .m-box__text {
      font-size: 45px;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <div class="m-box">
      <p class="m-box__text">Quisque velit nisi, pretium ut lacinia in, elementum id enim.</p>
    </div>
    
    <div class="m-box m-box--second">
      <p class="m-box__text">Curabitur non nulla sit amet nisl tempus convallis quis ac lectus. Praesent sapien massa, convallis a pellentesque nec, egestas non nisi. Nulla porttitor accumsan tincidunt. Sed porttitor lectus nibh. Praesent sapien massa, convallis a pellentesque nec, egestas non nisi.</p>
    </div>
    
    <div class="m-box m-box--red">
      <p class="m-box__text">Mauris blandit aliquet elit, eget tincidunt nibh pulvinar a. Donec sollicitudin molestie malesuada. Praesent sapien massa, convallis a pellentesque nec, egestas non nisi.</p>
    </div>
    
    <div class="m-box m-box--third">
      <p class="m-box__text">Mauris blandit aliquet elit, eget tincidunt nibh pulvinar a. Donec sollicitudin molestie malesuada. Praesent sapien massa, convallis a pellentesque nec, egestas non nisi.</p>
    </div>
    
    <div class="m-box">
      <p class="m-box__text">Quisque velit nisi, pretium ut lacinia in, elementum id enim.</p>
    </div>