为什么我的 intersectionObserver 将我的 querySelect 返回为未定义?

Why is my intersectionObserver returning my querySelect as undefined?

我试图使用 intersectionObserver 定位一个父元素和一个子元素,然后我有一个函数将父元素的背景更改为不同的颜色并旋转子元素。

此代码适用于父项 div,但子项 returns 未定义。 我是否无法使用 querySelector 定位子元素,或者 intersectionObserver 是否无法观察到多个元素?

let options = {
  threshold: 0.25
}

let observer = new IntersectionObserver(function(entries, observer) {
  entries.forEach(entry => {
    if (!entry.isIntersecting) {
      return;
    } else {
      console.log(entry.target);
      console.log(entry.sticky);
      alert('INTERSECTING!');
      entry.target.classList.toggle("red");
      entry.sticky.classList.toggle("rotate");
    }
  });
}, options);

let target = document.querySelector('.placeholder__div__large');
let sticky = document.querySelector('.sticky__container');

observer.observe(target, sticky);
.placeholder__div__large {
  height: 200vh;
  width: 100vw;
  display: flex;
  align-items: center;
  justify-content: center;
  color: white;
  background: black;
  transition: 2s;
}

.sticky__container {
  position: sticky;
  top: 100px;
  width: 200px;
  height: 200px;
}

.sticky__item {
  display: flex;
  justify-content: center;
  align-items: center;
  text-align: center;
  background: white;
  color: black;
  width: 100%;
  height: 100%;
}

.red {
  background: red;
  transition: 2s;
}

.rotate {
  transform: rotate(180deg);
}
<div class="placeholder__div__large">
  <div class="sticky__container">
    <div class="sticky__item">STICKY ITEM</div>
  </div>
</div>

您想观察粘性元素,如果它与您想要更改粘性的父元素重叠(在阈值内),请将其旋转并将父元素更改为背景红色。

因此,要设置我们要观察粘性的观察者。我们不需要观察这两个元素。我们还想设置一个阈值,所以这是选项的来源:

observer.observe(sticky, options)

在回调函数中,我们知道该条目将是粘性的,因为这是我们正在观察的唯一条目,因此您可以安全地保留它 - 如果 isIntersecting 则进行更改。您已经在 J​​S 中设置了 target 和 sticky 这两个元素,因此使用它们进行更改,您不需要参考条目来找到它们(并且 entry.sticky 无论如何都没有意义)。

我不确定最终目标是什么,因为变化只发生在交叉点上,即在非交叉点上不会回到原来的状态,但这里有一个颜色和旋转变化的片段在问题中设置:

let options = {
  threshold: 0.25
}

let observer = new IntersectionObserver(function(entries, observer) {
  entries.forEach(entry => {
    if (!entry.isIntersecting) {
      return;
    } else {
      target.classList.toggle("red");
      sticky.classList.toggle("rotate");
    }
  });
}, options);

let target = document.querySelector('.placeholder__div__large');
let sticky = document.querySelector('.sticky__container');

observer.observe(sticky);
.placeholder__div__large {
  height: 200vh;
  width: 100vw;
  display: flex;
  align-items: center;
  justify-content: center;
  color: white;
  background: black;
  transition: 2s;
}

.sticky__container {
  position: sticky;
  top: 100px;
  width: 200px;
  height: 200px;
}

.sticky__item {
  display: flex;
  justify-content: center;
  align-items: center;
  text-align: center;
  background: white;
  color: black;
  width: 100%;
  height: 100%;
}

.red {
  background: red;
  transition: 2s;
}

.rotate {
  transform: rotate(180deg);
}
<div class="placeholder__div__large">
  <div class="sticky__container">
    <div class="sticky__item">STICKY ITEM</div>
  </div>
</div>

你不能通过将它们全部传递给.observe来观察多个元素,你必须多次调用它。

此外,我假设您更愿意这样做(我不确定我是否正确,但您的部分代码对我来说没有任何意义):

let options = {
  threshold: 0.25
}

const observer = new IntersectionObserver(function(entries, observer) {
  entries.forEach(entry => {
    console.log('INTERSECTING with', entry.target, entry.isIntersecting);
    entry.target.classList.toggle("intersect", entry.isIntersecting);
  });
}, options);

const target = document.querySelector('.placeholder__div__large');
const sticky = document.querySelector('.sticky__container');

observer.observe(target);
observer.observe(sticky);
.placeholder__div__large {
  height: 200vh;
  width: 100vw;
  display: flex;
  align-items: center;
  justify-content: center;
  color: white;
  background: black;
  transition: 2s;
}

.sticky__container {
  position: sticky;
  top: 100px;
  width: 200px;
  height: 200px;
}

.sticky__item {
  display: flex;
  justify-content: center;
  align-items: center;
  text-align: center;
  background: white;
  color: black;
  width: 100%;
  height: 100%;
}

.red-whenintersect.intersect {
  background: red;
  transition: 2s;
}

.rotate-whenintersect.intersect {
  transform: rotate(180deg);
}
<div class="placeholder__div__large red-whenintersect">
  <div class="sticky__container">
    <div class="sticky__item rotate-whenintersect">STICKY ITEM</div>
  </div>
</div>