'Running an if statement inside a querySelectorAll Node List
I am building a blog post layout which requires some metadata to sit on one side and stay in place as the content scrolls, using position: sticky.
This works fine but some types of content stretch to 100% width, so collide with the metadata as they scroll by. I am looking to run an event listener on scroll which compares the position of both and adds a class to the sticky element, giving it opacity:0 as the other passes over it.
This works fine when there is only one full width (.fw) element on the page:
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");
    }
});
However, the post content is created dynamically and there may be more than one .fw per page. I am therefore trying to gather all instances using querySelectorAll for my second variable, but I cannot get this to work.
I am this far in:
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");
    }
  });
});
But it just isn't working. Doubtless I have made some obvious error or omission.
First instance only working in situ: https://hba.matmartin.studio/henry-v-donmar-warehouse/
Simplified codepen: https://codepen.io/MMS_/pen/VwQvvpm
With thanks to anyone who can help.
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>
Solution 1:[1]
The code below should achieve the behavior you're looking for. The problem was that the later .fw elements in the list were updating the visibility of the meta element.
I changed the loop to a for...of format and added a break to stop the loop when it is hidden, and did a bit of refactoring.
Hope this works!
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");
      }
    }
  });
    					Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source | 
|---|---|
| Solution 1 | misterjingles | 
