多个HTML元素的相同交集观察器

时间:2019-02-25 12:46:57

标签: javascript intersection-observer

我正在努力做到这一点,以便当某些文本项停止与深色背景重叠时,随着用户滚动,它们将分别逐个更改颜色。所有文本项均为position: fixed

编辑:MDN文档说(重点是我):

  

Intersection Observer API提供了一种异步观察的方法   目标元素与 祖先 的交集的变化   元素

我认为这意味着无法解决我的问题,因为我要监视重叠的元素不是我在options对象中指定的root的子元素。

如果重叠元素不是另一个元素的子元素,是否有任何方法可以检测到重叠?

if ('IntersectionObserver' in window) {

    const options = {
        root: document.getElementById('flow-landing'),
        rootMargin: '0px',
        threshold: 0
      }


    var callback = function(entries, observer) { 
            entries.forEach(entry => {

                if (entry.isIntersecting) {
                    entry.target.style.color = "white";
                }
                else {
                    entry.target.style.color = null;
                }
            });
          };

    const observer = new IntersectionObserver(callback, options);

    var targets = [Array.from(document.querySelectorAll('.social-item')), Array.from(document.querySelectorAll('.additional-item'))].flat();

    targets.forEach(target => 
        observer.observe(target));
}

没有任何控制台错误,但是代码没有执行任何操作。

3 个答案:

答案 0 :(得分:2)

您可以做类似的事情,至少对我有帮助:

document.querySelectorAll('.social-item').forEach((i) => {
    if (i) {
        const observer = new IntersectionObserver((entries) => {
            observerCallback(entries, observer, i)
        },
        {threshold: 1});    
        observer.observe(i);
    }
})

const observerCallback = (entries, observer, header) => {
    entries.forEach((entry, i) => {
         if (entry.isIntersecting) {
             entry.target.style.color = "white";
         }
         else {
             entry.target.style.color = null;
         }
    });
};

答案 1 :(得分:1)

稍微修改 Ruslan 的答案,因为在他的答案中,正在创建多个 Intersection Observer 对象。

通过对多个元素调用 .observe(),可以使用同一个观察者观察多个元素。

let observerOptions = {
    rootMargin: '0px',
    threshold: 0.5
}

var observer = new IntersectionObserver(observerCallback, observerOptions);

function observerCallback(entries, observer) {
    entries.forEach(entry => {
        if(entry.isIntersecting) {
          //do something
        }
    });
};

let target = '.targetSelector';
document.querySelectorAll(target).forEach((i) => {
    if (i) {
        observer.observe(i);
    }
});

答案 2 :(得分:0)

您可以使用offsetTopoffsetHeight属性代替IntersectionObserver API。

例如,当用户滚动时,您可以检查offsetTop的{​​{1}}是否大于{{1}的element 2 1}}。

警告:请使用防抖功能,因为用户滚动时,滚动事件的处理函数将被称为 每个像素一次 ,只需想象一下性能噩梦如果用户滚动600-1000像素,就会发生这种情况。

LoDash documentationit's debounce function描述为:

  

” [[一个函数,该函数创建一个防抖动的函数,该函数将调用offsetTop(处理程序)延迟到自上次调用防抖动的函数offsetHeight(时间)毫秒后开始。 “

如果您不使用LoDash,则可以使用以下Vanilla JavaScript反跳功能:

element 1

如果func “相交” wait,这是允许您“做事” 的代码。

function debounce(handler, time) {
  var timeout;
  return function() {
    var self = this, args = arguments;
    clearTimeout(timeout);
    timeout = setTimeout(function() {
      return handler.apply(self, args);
    }, time);
  };
}

如果看起来很复杂或难以阅读,这里是相同的代码,分为较小的块:

element 2

注释和信息:

  1. 您可以使用element 1let element_1 = document.querySelector("#my-element-1"); let element_2 = document.querySelector("#my-element-2"); window.addEventListener("scroll", debounce(() => { if(element_2.offsetTop > element_1.offsetTop && element_2.offsetTop < element_1.offsetHeight) { console.log("The elements are intersecting."); } }, 100)); 运算符代替let element_1 = document.querySelector("#my-element-1"); let element_2 = document.querySelector("#my-element-2"); window.addEventListener("scroll", debounce(() => { let x = element_2.offsetTop > element_1.offsetTop; let y = element_2.offsetTop < element_1.offsetHeight; if(x && y) { console.log("The elements are intersecting."); } }, 250)); >=运算符
  2. 过长的<=时间可能会使效果看起来不自然且被强制。

祝你好运。