如何更改滚动上透明 header 的文本颜色,具体取决于它重叠的 div

How to change the text color of a transparent header on scroll, depending on the div it overlaps

我有一个带有透明背景的header,我试图让header的文本根据[=45=的背景在白色和黑色之间改变颜色] 它是重叠的。

到目前为止,我已经设法将 .color-menu 的 class 添加到我希望 header 为黑色的所有 div。

然后我让它在 .color-menu div 到达页面顶部时将 .dark-menu 的 class 添加到 header。

问题是它只适用于第一个。colour-menu div。当它在视口中时它将变为黑色,并在下一个 div 时变回白色,但是当下一个 .color-menu div 到达顶部时它不会改变。

因此,.each 功能似乎无法正常工作,但我不确定如何修复它。

$(window).scroll(function() {
 $('.color-menu').each(function(i){
  var top_of_element = $(".color-menu").offset().top;
  var bottom_of_element = $(".color-menu").offset().top + $(".color-menu").outerHeight();
  var top_of_screen = $(window).scrollTop();

  if ((top_of_screen > top_of_element) && (top_of_screen < bottom_of_element)) {
    $(".header").addClass("dark-menu");
  } else {
    $(".header").removeClass("dark-menu");
  }
 });
});

更新:我也尝试过使用 $(this) 但是当它改变颜色时它真的会失败。

$(window).scroll(function() {
 $('.color-menu').each(function(i){
  var top_of_element = $(this).offset().top;
  var bottom_of_element = $(this).offset().top + $(this).outerHeight();
  var top_of_screen = $(window).scrollTop();

  if ((top_of_screen > top_of_element) && (top_of_screen < bottom_of_element)) {
    $(".header").addClass("dark-menu");
  } else {
    $(".header").removeClass("dark-menu");
  }
});
});

下面是我的代码的简化版本作为示例:

$(document).ready(function() {
  $(".white").addClass("color-menu");
  $(".white-bold").addClass("color-menu");
  $(".light").addClass("color-menu");
  $(".light-bold").addClass("color-menu");
  $(".bright").addClass("color-menu");
});

$(window).scroll(function() {
  $('.color-menu').each(function(i){
    var top_of_element = $(".color-menu").offset().top;
    var bottom_of_element = $(".color-menu").offset().top + $(".color-menu").outerHeight();
    var top_of_screen = $(window).scrollTop();

    if ((top_of_screen > top_of_element) && (top_of_screen < bottom_of_element)) {
      $(".header").addClass("dark-menu");
    } else {
      $(".header").removeClass("dark-menu");
    }
  });
});
.header {
  width: 100%;
  background: rgba(0,0,0,0);
  margin: 0;
  padding:10px;
  position: fixed;
  text-align: center;
}
.header a {
  color: white;
  font-size: 2rem;
  text-transform: uppercase;
}
.dark-menu a{
  color: black;
}
.black {
  background-color: black;
  height: 200px;
}
.white, .white-bold, .light, .light-bold, .bright {
  background-color: white;
  height: 200px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="header">
  <a>This is the header</a>
</div>
<div class ="black"></div>
<div class ="white"></div>
<div class ="black"></div>
<div class ="white-bold"></div>
<div class ="black"></div>
<div class ="light"></div>
<div class ="black"></div>
<div class ="light-bold"></div>
<div class ="black"></div>
<div class ="bright"></div>

你的代码中发生的事情是,在滚动时,你循环遍历每个 color-menu div 并添加 class 如果它是当前的......然后代码 继续 遍历数组中的剩余元素并再次将其删除,因为页面不在另一个 div.

我已经解释了 step-by-step 在示例之后您需要进行哪些更改才能使其正常工作,但首先您可以在此处看到它的工作情况:

工作示例

$(document).ready(function() {
  $(".white").addClass("color-menu");
  $(".white-bold").addClass("color-menu");
  $(".light").addClass("color-menu");
  $(".light-bold").addClass("color-menu");
  $(".bright").addClass("color-menu");

  $(window).scroll(function() {

    var inColorMenu = false;            /* initialise var to store if we are in color-menu */
    var top_of_screen = $(window).scrollTop();          /* just get this once outside loop */

    /* Loop through each color-menu element and check if we are in one */
    $('.color-menu').each(function(i) {
      var top_of_element = $(this).offset().top;
      var bottom_of_element = top_of_element + $(this).outerHeight();

      /* if we are in a color-menu element, set our var to true and stop processing */
      if ((top_of_screen > top_of_element) && (top_of_screen < bottom_of_element)) {
        inColorMenu = true;
        return false;         /* N.B. need to return "false" to break from the "each" loop */
      }
    });

    if (inColorMenu) {
      $(".header").addClass("dark-menu");
    } else {
      $(".header").removeClass("dark-menu");
    }
  });
});
.header {
  width: 100%;
  background: rgba(0, 0, 0, 0);
  margin: 0;
  padding: 10px;
  position: fixed;
  text-align: center;
}

.header a {
  color: white;
  font-size: 2rem;
  text-transform: uppercase;
}

.header.dark-menu a {
  color: black;
}

.black {
  background-color: black;
  height: 200px;
}

.white,
.white-bold,
.light,
.light-bold,
.bright {
  background-color: white;
  height: 200px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="header">
  <a>This is the header</a>
</div>
<div class="black"></div>
<div class="white"></div>
<div class="black"></div>
<div class="white-bold"></div>
<div class="black"></div>
<div class="light"></div>
<div class="black"></div>
<div class="light-bold"></div>
<div class="black"></div>
<div class="bright"></div>

这是如何工作的:

  1. 声明一个变量来记录我们是否在“color-menu”class中,并将其初始化为false,例如:
var inColorMenu = false;

  1. 当遍历 $('.color-menu').each 时,如果我们位于 div 之一的顶部和底部之间(您的代码已经检测到),则将我们的变量设置为 true 以记录这一点。
    我们还可以 return false 打破 each 循环并停止处理其余元素(没有这个它仍然可以工作,我们只是减少了所需的处理量):
if ((top_of_screen > top_of_element) && (top_of_screen < bottom_of_element)) {
    inColorMenu = true;
    return false;         /* N.B. need to return "false" to break from the "each" loop */
}

  1. 最后,在我们完成 $('.color-menu').each 循环后,如果 inColorMenu 为真,我们知道我们在 color-menu div 中,所以我们添加 dark-menu class 到 header,否则我们删除它:
if (inColorMenu) {
    $(".header").addClass("dark-menu");
} else {
    $(".header").removeClass("dark-menu");
}

  1. 注意:您需要在获取 offset().topouterHeight() 时使用 $(this),以便获取 current 的值循环中的元素。 $(".color-menu") 使用此 class 获取未指定元素的值,因此将不起作用。