运行 querySelectorAll 节点列表中的 if 语句

Running an if statement inside a querySelectorAll Node List

我正在构建一个博客 post 布局,它需要一些元数据位于一侧并在内容滚动时保持原位,使用 position: sticky

这很好用,但某些类型的内容会拉伸到 100% 宽度,因此在滚动时会与元数据发生冲突。我正在寻找 运行 滚动上的事件侦听器,它比较两者的位置并向粘性元素添加 class,当另一个通过它时给它 opacity:0

当页面上只有一个全宽 (.fw) 元素时,此方法工作正常:

window.addEventListener('scroll', function() {
var a = document.querySelector('.postmeta-sticky').getBoundingClientRect(),
    b = document.querySelector('.fw').getBoundingClientRect();
    if((b.top <= (a.top + a.height)) && ((b.top + b.height) > a.top)) {
        $(".postmeta-wrap").addClass("overlap");
    } else {
        $(".postmeta-wrap").removeClass("overlap");
    }
});

但是,post 内容是动态创建的,每页可能有多个 .fw。因此,我正在尝试使用 querySelectorAll 收集所有实例作为我的第二个变量,但我无法让它工作。

我目前在:

window.addEventListener('scroll', function(){
  var a = document.querySelector(".postmeta-sticky").getBoundingClientRect(),
      objects = document.querySelectorAll(".fw");
  objects.forEach(function(object) {
    b = object.getBoundingClientRect();
    if ((b.top <= (a.top + a.height)) && ((b.top + b.height) > a.top)) {
      $(".postmeta-wrap").addClass("overlap");
    } else {
      $(".postmeta-wrap").removeClass("overlap");
    }
  });
});

但这就是行不通。毫无疑问,我犯了一些明显的错误或遗漏。

一审仅在原​​地工作:https://hba.matmartin.studio/henry-v-donmar-warehouse/

简化代码笔:https://codepen.io/MMS_/pen/VwQvvpm

感谢任何能提供帮助的人。

jQuery(document).ready(function($) {
  window.addEventListener('scroll', function() {
    var a = document.querySelector(".sticky-content").getBoundingClientRect(),
      objects = document.querySelectorAll(".fw");
    objects.forEach(function(object) {
      b = object.getBoundingClientRect();
      if ((b.top <= (a.top + a.height)) && ((b.top + b.height) > a.top)) {
        $(".sticky-wrap").addClass("overlap");
      } else {
        $(".sticky-wrap").removeClass("overlap");
      }
    });
  });
});
.content {
  box-sizing: border-box;
  position: relative;
}

.sticky-wrap {
  position: absolute;
  height: 100%;
  width: 33%;
  z-index: 0;
}

.sticky-wrap.overlap {
  opacity: 0;
}

.sticky-content {
  position: sticky;
  top: 0;
  left: 0;
  width: 100%;
  height: 112px;
  padding: 24px 0;
  background: #e9e9e9;
}

.scrolling-content {
  width: 100%;
  position: relative;
  z-index: 1;
}

.scrolling-element {
  width: 66%;
  height: 160px;
  background: #d56d56;
  margin: 0 0 48px auto;
}

.scrolling-element.fw {
  width: 100%;
  background: #9dc9dc;
  opacity: 0.5;
}

.page-head {
  width: 100%;
  height: 72px;
  background: #F6F6F6;
}

.page-end {
  width: 100%;
  height: 480px;
  background: #383838;
}
<div class="page-head"></div>
<div class="content">
  <div class="sticky-wrap">
    <div class="sticky-content">
      <ul>
        <li>This info</li>
        <li>sticks around</li>
        <li>for a bit</li>
      </ul>
    </div>
  </div>
  <div class="scrolling-content">
    <div class="scrolling-element"></div>
    <div class="scrolling-element fw"></div>
    <div class="scrolling-element"></div>
    <div class="scrolling-element fw"></div>
    <div class="scrolling-element"></div>
    <div class="scrolling-element"></div>
  </div>
</div>
<div class="page-end"></div>

<script src="https://code.jquery.com/jquery-1.12.3.js" integrity="sha256-1XMpEtA4eKXNNpXcJ1pmMPs8JV+nwLdEqwiJeCQEkyc=" crossorigin="anonymous"></script>

下面的代码应该可以实现您正在寻找的行为。问题是列表中后面的 .fw 元素正在更新元元素的可见性。

我将循环更改为 for...of 格式并添加了一个 break 以在隐藏时停止循环,并进行了一些重构。

希望这有效!

window.addEventListener('scroll', function(){
    var sticky = document.querySelector(".sticky-content");
    var a = sticky.getBoundingClientRect();
    var objects = document.querySelectorAll(".fw");
    for (object of objects) {
      b = object.getBoundingClientRect();
      if ((b.top <= (a.top + a.height)) && ((b.top + b.height) > a.top)) {
        sticky.parentNode.classList.add("overlap");
        break;
      } else {
        sticky.parentNode.classList.remove("overlap");
      }
    }
  });