当用户向下滚动然后返回时更改颜色

时间:2017-07-30 22:28:12

标签: javascript jquery html css

我有几个div垂直排列在另一个上面,从这里开始我将称为面板。每个面板都具有视口的宽度和高度。所有面板始终具有相同的背景颜色。最初,那种颜色是黑色。

每个其他面板都是空的,并且充当实际具有内容的面板之间的间隙。订单是这样的:

  1. 内容
  2. 没有内容
  3. 内容
  4. 没有内容
  5. 内容
  6. 我想要做的是,当用户向下滚动足够使面板 内容不在视野范围内时,颜色应该从黑色变为白色。然后,一旦他们滚动到第二个面板足够远,内容不在视野范围内,它应该改回来。

    这是我无法弄清楚的部分。到目前为止,我的代码有一个工作演示:

    $(document).scroll(function() {
    
      var viewportHeight = $("html").outerHeight();
      var currentY = $(document).scrollTop();
      if (currentY % viewportHeight != 0) {
        lighten();
      } else {
        darken();
      }
    });
    
    function darken() {
      $("body").css("background-color", "black");
      $(".panel.content").css("color", "white");
    }
    
    function lighten() {
      $("body").css("background-color", "white");
      $(".panel.content").css("color", "black");
    }
    html,
    body,
    .panel {
      width: 100%;
      height: 100%;
    }
    
    body {
      background-color: black;
      overflow-y: visible;
      overflow-x: hidden;
      transition: background-color 500ms linear;
    }
    
    .panel {
      border: 2px solid red;
    }
    
    .content {
      color: white;
      text-align: center;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
    
    <body>
      <div class="panel content">
        <h2> CONTENT </h2>
      </div>
      <div class="panel blank">
      </div>
      <div class="panel content">
        <h2> CONTENT </h2>
      </div>
      <div class="panel blank">
      </div>
      <div class="panel content">
        <h2> CONTENT </h2>
      </div>
    </body>

    正如您所看到的,我的代码远没有达到预期的效果。订单不仅错误,主要问题是它只会在用户处于确切的Y位置时才会触发更改。

    订单应该是:

    1. 黑色
    2. 黑色
    3. 黑色
    4. 黑色
    5. 黑色
    6. 我该怎么做?

7 个答案:

答案 0 :(得分:2)

$(document).scroll(function() {

  var viewportHeight = $("html").outerHeight();
  var currentY = $(document).scrollTop();
  var panelNumber = Math.floor(currentY / viewportHeight);
  if (panelNumber % 4 === 1 || panelNumber % 4 === 2) {
    lighten();
  } else {
    darken();
  }
});

function darken() {
  $("body").css("background-color", "black");
  $(".panel.content").css("color", "white");
}

function lighten() {
  $("body").css("background-color", "white");
  $(".panel.content").css("color", "black");
}
html,
body,
.panel {
  width: 100%;
  height: 100%;
}

body {
  background-color: black;
  overflow-y: visible;
  overflow-x: hidden;
  transition: background-color 500ms linear;
}

.panel {
  border: 2px solid red;
}

.content {
  color: white;
  text-align: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<body>
  <div class="panel content">
    <h2> CONTENT </h2>
  </div>
  <div class="panel blank">
  </div>
  <div class="panel content">
    <h2> CONTENT </h2>
  </div>
  <div class="panel blank">
  </div>
  <div class="panel content">
    <h2> CONTENT </h2>
  </div>
  <div class="panel blank">
  </div>
  <div class="panel content">
    <h2> CONTENT </h2>
  </div>
  <div class="panel blank">
  </div>
</body>

  

订单不仅错误,主要问题是它只会触发   当用户处于确切的Y时,发生变化。

是的......那是对的。 currentY % viewportHeight != 0无效。滚动并不顺利。向下拉动滚动条可能会导致10000 px / sec的变化,但是浏览器渲染60fps,这意味着你的currentY(scroll-y)每帧会增加150px(你的预期变化为1px)。因此,如果您的代码包含if(currentY === 100){}肯定无法正常工作。 currentY可能包含0,50,80,99,120,...等值。

应该清楚currentY % viewportHeight != x并没有太大的不同。

所以if(0<currentY<500)将是更好的选择。

现在假设viewportHeight = 500。我们可以获得panelNumber = Math.floor(currentY/viewportHeight)(=&gt; 0,1,2,3,4,5 ...)

(不清楚你的问题)假设你想拥有 面板:0 =&gt;黑色,1 =&gt;白色,2 =&gt;白色,3 =&gt;黑色,4 =&gt;黑色... 你可以通过panelNumber%4==0 || panelNumber%4==3获得黑色。

[如果您想要不同的东西,请相应更改]

答案 1 :(得分:2)

我知道它有点晚了,但是我为此做了一个解决方案,没有时间发布它。

所以:&#34;我的解决方案有何不同?&#34;

我从所有 .blank div获得从顶部开始的差异值,然后检查view-port所在的位置。这允许您使用边框,在其间添加任何其他div,更改div的大小,这不会失去功能。

&#13;
&#13;
var elem = document.getElementsByClassName("blank");
var i;
var marks = [];
for (i = 0; i < elem.length; i++) {
  var rect = elem[i].getBoundingClientRect();
  marks.push(rect.top);
}

$(document).scroll(function() {
  if (findi() % 2 == 1) {
    lighten();
  } else {
    darken();
  }
});

function findi() {
  pos = 0;
  for (i = 0; i < marks.length; i++) {
    if (marks[i] < $(document).scrollTop()) {
      pos++;
    }
  }
  return (pos);
}

function darken() {
  $("body").css("background-color", "black");
  $(".panel.content").css("color", "white");
}

function lighten() {
  $("body").css("background-color", "white");
  $(".panel.content").css("color", "black");
}
&#13;
body {
  background-color: black;
  overflow-y: visible;
  overflow-x: hidden;
  transition: background-color 500ms linear;
}

html,
body {
  padding: 0;
  margin: 0;
}

html,
body,
.panel {
  width: 100%;
  height: 100%;
}

.panel {
  border-bottom: 32px solid red;
}

.content {
  color: white;
  text-align: center;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="panel content">
  <h2> CONTENT </h2>
</div>
<div class="panel blank">
</div>
<div class="panel content">
  <h2> CONTENT </h2>
</div>
<div class="panel blank">
</div>
<div class="panel content">
  <h2> CONTENT </h2>
</div>
<div class="panel blank">
</div>
<div class="panel content">
  <h2> CONTENT </h2>
</div>
<div class="panel blank">
</div>
<div class="panel content">
  <h2> CONTENT </h2>
</div>
<div class="panel blank">
</div>
<div class="panel content">
  <h2> CONTENT </h2>
</div>
<div class="panel blank">
</div>
<div class="panel content">
  <h2> CONTENT </h2>
</div>
<div class="panel blank">
</div>
<div class="panel content">
  <h2> CONTENT </h2>
</div>
<div class="panel blank">
</div>
<div class="panel content">
  <h2> CONTENT </h2>
</div>
&#13;
&#13;
&#13;

答案 2 :(得分:1)

您可以在.hover()上使用$(document).ready();我已添加了一个示例,如果它适合您。

&#13;
&#13;
$(document).ready(function() {

  $(".panel.content").hover(function(){
       $("body").css("background-color", "white");
       $(this).css("color", "black");
  },function(){
       $("body").css("background-color", "black");
       $(this).css("color", "white");
  });
  
});

$(document).scroll(function() {

  $(".panel.content").hover(function(){
       $("body").css("background-color", "white");
       $(this).css("color", "black");
  },function(){
       $("body").css("background-color", "black");
       $(this).css("color", "white");
  });
  
});
&#13;
html,
body,
.panel {
  width: 100%;
  height: 100%;
}

body {
  background-color: black;
  overflow-y: visible;
  overflow-x: hidden;
  transition: background-color 500ms linear;
}

.panel {
  border: 2px solid red;
}

.content {
  color: white;
  text-align: center;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>

<body>
  <div class="panel content">
    <h2> CONTENT </h2>
  </div>
  <div class="panel blank">
  </div>
  <div class="panel content">
    <h2> CONTENT </h2>
  </div>
  <div class="panel blank">
  </div>
  <div class="panel content">
    <h2> CONTENT </h2>
  </div>
</body>
&#13;
&#13;
&#13;

答案 3 :(得分:1)

在代码中添加条件

Math.floor(currentY / viewportHeight) % 4 == 1 || Math.floor(currentY / viewportHeight) % 4 == 2

您的代码现在正在运行。

<强>测试

如果在java中运行此代码,它将显示与您预期相同的输出。

public static void main(String...arr){
    for(int i = 0; i<100; i++){
        if(i%4 ==1 || i%4 == 2){
            System.out.println("true");
        } else {
            System.out.println("false");
        }
    }
}

$(document).scroll(function() {

      var viewportHeight = $("html").outerHeight();
      var currentY = $(document).scrollTop();
      
      if (Math.floor(currentY / viewportHeight) % 4 == 1 || Math.floor(currentY / viewportHeight) % 4 == 2) {
        lighten();
      } else {
        darken();
      }
    });
    
    function darken() {
      $("body").css("background-color", "black");
      $(".panel.content").css("color", "white");
    }

    function lighten() {
      $("body").css("background-color", "white");
      $(".panel.content").css("color", "black");
    }
  html,
    body,
    .panel {
      width: 100%;
      height: 100%;
    }

    body {
      background-color: black;
      overflow-y: visible;
      overflow-x: hidden;
      transition: background-color 500ms linear;
    }

    .panel {
      border: 2px solid red;
    }

    .content {
      color: white;
      text-align: center;
    }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
      <div class="panel content">
        <h2> CONTENT </h2>
      </div>
      <div class="panel blank">
      </div>
      <div class="panel content">
        <h2> CONTENT </h2>
      </div>
      <div class="panel blank">
      </div>
      <div class="panel content">
        <h2> CONTENT </h2>
      </div>
    </body>

答案 4 :(得分:1)

我已经制作了这样你可以选择哪个面板将背景颜色设置为白色/黑色。您可以通过添加班级&#39; black&#39;或者&#39;白色&#39;对它来说,虽然你要求它的方式完全有道理。 我的解决方案也使用一个类来改变身体的背景颜色。这样可以更容易地进行样式更改。

&#13;
&#13;
$(document).ready(init)

function init(){
	$(document).scroll(updateBackground)
	updateBackground()
}

function updateBackground(){
	var w = $(window).width()
	var h = $(window).height()
	var panels = $('.panel') // get all panels on page

	for(var i=0;i<panels.length;i++){ // loop though each panel
		var panel = panels.eq(i) // get the current panel
		var panel_y = panel.offset().top - $(document).scrollTop() // get the panels y coordinate relative to the window
		var panel_height = panel.height() // get the panels height
		if(panel_y<=0 && panel_y+panel_height>0){ // check if the panel is in the visible area
			if(panel.hasClass('black')){ // check if the panel is set to make the background black
				$('body').removeClass('white')
				$('body').addClass('black')
			}else if(panel.hasClass('white')){
				$('body').removeClass('black')
				$('body').addClass('white')
			}
			return // return, because we already found the visible panel
		}
	}
}
&#13;
html{
  height: 100%
}
body{
	margin: 0;
	padding: 0;
	transition: background-color 500ms linear;
  height: 100%
}
body.white{
	background-color: white;
	color: black;
}
body.black{
	background-color: black;
	color: white;
}
.panel{
	width: 100%;
	height: 100%;
	box-sizing: border-box;
	padding: 50px;
	border: solid 1px #888888;
	text-align: center;
	overflow: hidden;
}
.panel > h1{
	font-size: 38pt;
} 
.panel > p{
	font-size: 18pt;
	line-height: 200%;
} 
&#13;
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
</head
<body>

<div class="panel with-content black">
	<h1>Content</h1>
	<p>
	    Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
	</p>
</div>

<div class="panel gap white"></div>

<div class="panel with-content white">
	<h1>Content</h1>
	<p>
	    Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
	</p>
</div>

<div class="panel gap black"></div>

<div class="panel with-content black">
	<h1>Content</h1>
	<p>
	    Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
	</p>
</div>

<div class="panel gap white"></div>

<div class="panel with-content white">
	<h1>Content</h1>
	<p>
	    Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
	</p>
</div>

<div class="panel gap black"></div>

<div class="panel with-content black">
	<h1>Content</h1>
	<p>
	    Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
	</p>
</div>

</body>
</html>
&#13;
&#13;
&#13;

答案 5 :(得分:1)

这是我的解决方案。我很确定这是你需要的订单。

(function() {
    var lastfunc = darken;
    $(document).scroll(function() {
        var y = $(document).scrollTop();
        var x = $("html").outerHeight();
        var func = (Math.floor(((y + x) / (2 * x))) % 2) ? lighten : darken;
        if (func !== lastfunc) {
            lastfunc = func;
            func();
        }
    });
})();

执行以下操作:

  1. 创建变量lastfunc以跟踪我们调用的最后一件事。
  2. 获取用户的Y和视口的高度。
  3. 使用邪恶的分解数学来获得一个bool,它决定将lighten()darken()分配给func这两个函数中的哪一个。
  4. 检查lastfunc是否等于func,以查看是否需要进行更改。
    • 如果不相等,请致电func()并将lastfunc设为func
  5. 这有以下好处:

    1. 所有这些都是为了防止lastfunc成为全球性的。
    2. 数学很扎实。
    3. 只有在需要更改时才会调用样式修改功能
    4. 我还优化了您的darken()lighten()功能:

      function darken() {
          document.body.style.backgroundColor = "black";
          $(".panel.content").css("color", "white");
      }
      
      function lighten() {
          document.body.style.backgroundColor = "white";
          $(".panel.content").css("color", "white");
      }
      

      这种轻微的优化可以节省jQuery找到body的麻烦,这可以节省几毫秒。没有太大的区别,但这是最佳的。

      附加说明:如果您能够摆脱lightendarken中的第二个样式更改,我们可以完全消除函数调用的开销,并完成所有操作在scroll()内:

      (function() { 
          var lastColor;
          $(document).scroll(function() {
              var y = $(document).scrollTop();
              var color = (Math.floor(((y + x) / (2 * x))) % 2) ? "red" : "blue";
              if (color !== lastColor) {
                  lastColor = color;
                  document.body.style.color = color;
              }
          });
      })();
      

      演示第一个解决方案:

      (function() {
          var lastfunc = darken;
          $(document).scroll(function() {
              var y = $(document).scrollTop();
              var x = $("html").outerHeight();
              var func = (Math.floor(((y + x) / (2 * x))) % 2) ? lighten : darken;
              if (func !== lastfunc) {
                  lastfunc = func;
                  func();
              }
          });
      })();
      
      function darken() {
          document.body.style.backgroundColor = "black";
          $(".panel.content").css("color", "white");
      }
      
      function lighten() {
          document.body.style.backgroundColor = "white";
          $(".panel.content").css("color", "white");
      }
      html,
      body,
      .panel {
        width: 100%;
        height: 100%;
      }
      
      body {
        background-color: black;
        overflow-y: visible;
        overflow-x: hidden;
        transition: background-color 500ms linear;
      }
      
      .panel {
        border: 2px solid red;
      }
      
      .content {
        color: white;
        text-align: center;
      }
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
      
      <body>
        <div class="panel content">
          <h2> CONTENT </h2>
        </div>
        <div class="panel blank">
        </div>
        <div class="panel content">
          <h2> CONTENT </h2>
        </div>
        <div class="panel blank">
        </div>
        <div class="panel content">
          <h2> CONTENT </h2>
        </div>
      </body>

答案 6 :(得分:0)

  

我想要做的是,当用户向下滚动足以让内容不在视图中的面板时,颜色应该从黑色变为白色。然后,一旦他们滚动到第二个面板足够远,内容不在视野范围内,它就应该改回来。

此声明与您提到的顺序冲突。从声明中可以看出,颜色变化应该是交替的,但问题中提到的顺序不是替代。

请参阅下面的代码,通过滚动来更改备用div上的颜色。

$(document).scroll(function() {

  var viewportHeight = $("html").outerHeight();
  var currentY = $(document).scrollTop();
  
  if (Math.floor(currentY / viewportHeight) % 2) {
    lighten();
  } else {
    darken();
  }
});

function darken() {
  $("body").css("background-color", "black");
  $(".panel.content").css("color", "white");
}

function lighten() {
  $("body").css("background-color", "white");
  $(".panel.content").css("color", "black");
}
html,
body,
.panel {
  width: 100%;
  height: 100%;
}

body {
  background-color: black;
  overflow-y: visible;
  overflow-x: hidden;
  transition: background-color 500ms linear;
}

.panel {
  border: 2px solid red;
}

.content {
  color: white;
  text-align: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>

<body>
  <div class="panel content">
    <h2> CONTENT </h2>
  </div>
  <div class="panel blank">
  </div>
  <div class="panel content">
    <h2> CONTENT </h2>
  </div>
  <div class="panel blank">
  </div>
  <div class="panel content">
    <h2> CONTENT </h2>
  </div>
</body>