我正在使用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使用了怪异的回调迭代器逻辑,该逻辑在每次元素发生任何更改时都会执行(而不是使用事件驱动的模型)。

有什么想法,如何实现不改变其他元素或对象的每个元素一次调用?

最佳答案

正如James在注释中指出的那样,此问题最简单的解决方案是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);
    }
  });
}

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

关于javascript - 交叉口观察员: Call a function only once per element,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/53684503/

10-09 22:05