title: Intersection Observer: Call a function only once per element
body: <p>I'm using the <a href="https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API" rel="noreferrer">Intersection Observer API</a> to track the visibility of multiple element on a web page. When an element becomes visible, a function <code>callback()</code> should be executed. The restriction: For each element, the function may only be executed once.</p>
  
  <p>Here is my current implementation for a web analytics project:</p>
  
  <pre><code>const elements = document.querySelectorAll('[data-observable]');
  const callback = str =&gt; { console.log(str); };
  const observer = new IntersectionObserver(handleIntersection);
  
  elements.forEach(obs =&gt; {
    observer.observe(obs);
  });
  
  function handleIntersection(entries, observer){
    entries.forEach(entry =&gt; {
      if (entry.intersectionRatio &gt; 0) {
        // Call this function only once per element, without modifying entry object
        callback('observer-' + entry.target.getAttribute('data-observable'));
      }
    });
  }
  </code></pre>
  
  <p>I'm struggeling to find a solution that does not modify existing elements, the IntersectionObserver or the IntersectionObserverEntries.</p>
  
  <p>Usually I would use a closure to ensure that a function gets only executed once:</p>
  
  <pre><code>function once(func) {
    let executed = false;
    return function() {
      if (!executed) {
        executed = true;
        return func.apply(this, arguments);
      }
    };
  }
  </code></pre>
  
  <p>But in this case I have difficulties applying the function because IntersectionObserver uses a weird callback iterator logic that get's executed everytime any element changes (instead of using a event-driven model).</p>
  
  <p>Any ideas, how to implement a once per element function call that does not mutate other elements or objects? </p>