【问题标题】:Intersection Observer: Call a function only once per elementIntersection Observer:每个元素只调用一次函数
【发布时间】:2018-12-08 16:22:55
【问题描述】:

我正在使用Intersection Observer API 来跟踪网页上多个元素的可见性。当一个元素变得可见时,应该执行一个函数callback()。限制:对于每个元素,函数只能执行一次。

这是我目前对一个网络分析项目的实现:

const elements = document.querySelectorAll('[data-observable]');
const callback = str => { console.log(str); };
const observer = new IntersectionObserver(handleIntersection);

elements.forEach(obs => {
  observer.observe(obs);
});

function handleIntersection(entries, observer){
  entries.forEach(entry => {
    if (entry.intersectionRatio > 0) {
      // Call this function only once per element, without modifying entry object
      callback('observer-' + entry.target.getAttribute('data-observable'));
    }
  });
}

我正在努力寻找一个不修改现有元素、IntersectionObserver 或 IntersectionObserverEntries 的解决方案。

通常我会使用闭包来确保函数只执行一次:

function once(func) {
  let executed = false;
  return function() {
    if (!executed) {
      executed = true;
      return func.apply(this, arguments);
    }
  };
}

但在这种情况下,我很难应用该函数,因为 IntersectionObserver 使用了一个奇怪的回调迭代器逻辑,每次任何元素更改时都会执行该逻辑(而不是使用事件驱动模型)。

任何想法,如何实现一个不改变其他元素或对象的每个元素函数调用?

【问题讨论】:

  • IE不支持,你知道吗?
  • 是的,但我使用的是 polyfill。
  • 函数调用后还需要观察者吗?如果没有,一旦调用函数就不要观察它。 developer.mozilla.org/en-US/docs/Web/API/IntersectionObserver/…
  • 是的,因为我正在观察多个元素。另一方面,为每个元素注册一个观察者是可能的,但非常浪费。
  • 但是你只能对一个元素使用unobserve函数:observer.unobserve(entry.target);对于其他元素,观察者仍会调用

标签: javascript intersection-observer


【解决方案1】:

正如 James 在 cmets 中指出的那样,解决这个问题的最简单方法是 unobserving 元素一旦变得可见并调用了回调。

const elements = document.querySelectorAll('[data-observable]');
const callback = str => { console.log(str); };
const observer = new IntersectionObserver(handleIntersection);

elements.forEach(obs => {
  observer.observe(obs);
});

function handleIntersection(entries, observer){
  entries.forEach(entry => {
    if (entry.intersectionRatio > 0) {
      callback('observer-' + entry.target.getAttribute('data-observable')); 
      observer.unobserve(entry.target);
    }
  });
}

我没有找到任何可行的解决方案来使用闭包来控制调用函数的频率。

【讨论】:

    猜你喜欢
    • 2021-04-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多