【问题标题】:Why is my intersectionObserver returning my querySelect as undefined?为什么我的 intersectionObserver 将我的 querySelect 返回为未定义?
【发布时间】:2021-05-10 20:21:40
【问题描述】:

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

此代码适用于父 div,但子项返回未定义。 是我无法使用 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>

【问题讨论】:

标签: javascript html css queryselector


【解决方案1】:

你不能通过将它们全部传递给.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>

【讨论】:

  • 谢谢,这就是我想知道的,我真的不明白 Mozillas 页面上是否可以在一行中为观察者传递两个目标。
【解决方案2】:

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

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

observer.observe(sticky, options)

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

我不确定最终目标是什么,因为更改仅发生在交叉路口,即在非交叉路口不会回到原来的位置,但这里有一个颜色和旋转更改为的 sn-p在问题中设置:

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>

【讨论】:

    猜你喜欢
    • 2021-04-25
    • 2014-06-04
    • 2017-07-23
    • 2010-09-16
    • 1970-01-01
    • 1970-01-01
    • 2019-01-21
    • 2021-11-15
    • 2021-10-19
    相关资源
    最近更新 更多