【问题标题】:IntersactionObserver() only observes the first element of a row instead of allIntersactionObserver() 只观察一行的第一个元素而不是所有
【发布时间】:2020-11-25 21:15:02
【问题描述】:

我正在尝试使用 IntersectionObserver(),它的行为很奇怪:我使用了一个非常简单的布局,只有 8 个图像在同一个 div 和 flexbox 中,使用 wrap,所以基本上 8 个图像将它们自己定位在不同的行中,根据视口的大小。我首先对每个元素应用一个过滤器类(它添加一个模糊过滤器),然后在它们显示在屏幕上时将其删除:

HTML:

<div class="flex--cont">
            <div class="box box-2">
                <img src="img/1.jpg" alt="" class="img img-1">
            </div>
            <div class="box box-1">
                <img src="img/2.jpg" alt="" class="img img-2">
            </div>
            <div class="box box-3">
                <img src="img/3.jpg" alt="" class="img img-3">
            </div>
            <div class="box box-4">
                <img src="img/4.jpg" alt="" class="img img-4">
            </div>
            <div class="box box-5">
                <img src="img/5.jpg" alt="" class="img img-5">
            </div>
            <div class="box box-6">
                <img src="img/6.jpg" alt="" class="img img-6">
            </div>
            <div class="box box-7">
                <img src="img/7.jpg" alt="" class="img img-7">
            </div>
            <div class="box box-8">
                <img src="img/8.jpg" alt="" class="img img-8">
            </div>
        </div>

JAVASCRIPT

const allImage = Array.from(document.querySelectorAll(".img"));
allImage.forEach((img) => img.classList.add("filter"));

const removeFilter = function (entries, observer) {
  const [entry] = entries;
  const image = entry.target;
  image.classList.remove("filter");
};

const ImageObserver = new IntersectionObserver(removeFilter, {
  root: null,
  threshold: 0.15,
});

allImage.forEach((img) => ImageObserver.observe(img));

问题是观察者实际上只观察每行的第一个元素,所以如果我有 2 行,它只会得到第 1 和第 5 图像,如果我有 3 行,它会得到第 1、第 4 和第第 7 张图片以此类推。我确实已将其应用于所有图像。为什么要这样做?感谢您的回答!

【问题讨论】:

  • 能否在 stackblitz 中重现此问题?
  • 我会试试的。我会尽快发布????
  • 我是在 codepen 中完成的,但这说明了问题。我希望所有的正方形都变成蓝色,但只有每行的第一行变成蓝色codepen.io/andreauge/pen/ExgYqVB

标签: javascript intersection-observer


【解决方案1】:

只有第一个在改变,因为这就是你在改变颜色函数中的目标,只解构第一个数组元素:

const [entry] = entries;

但是,InteractionObserver 回调不是针对每个条目调用的,而是针对同时触发的所有条目;因此entries 数组包含所有正在观察的项目,您需要像这样检查isIntersecting 属性:

const changeColor = function(entries) {
  entries.forEach(entry => {
    if(entry.isIntersecting) {
      entry.target.style.background = 'blue';
    } else {
      entry.target.style.background = 'red';
    }
  })
}

来自 MDN 文档

let callback = (entries, observer) => {
  entries.forEach(entry => {
    // Each entry describes an intersection change for one observed
    // target element:
    //   entry.boundingClientRect
    //   entry.intersectionRatio
    //   entry.intersectionRect
    //   entry.isIntersecting
    //   entry.rootBounds
    //   entry.target
    //   entry.time
  });
};

【讨论】:

  • 嗯,这是一个非常完整且直截了当的答案。非常感谢你,安德鲁!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-21
  • 2023-03-11
  • 2017-03-13
  • 1970-01-01
  • 1970-01-01
  • 2011-03-13
相关资源
最近更新 更多