JSFiddle - React, Tailwind, and code Playground

by jacobwsmith

HTML

<div id="theAd">
  I'M THE AD!!!!
</div>

CSS

#theAd{
  background-color: red;
  width: 300px;
  height: 250px;
  text-align: center;
  font-size: 40px;
}

JavaScript

// ads.js

function logImpressionToServer() {
	console.log('logImpressionToServer');
}

function isVisible(boundingClientRect, intersectionRect) {
  return ((intersectionRect.width * intersectionRect.height) /
          (boundingClientRect.width * boundingClientRect.height) >= 0.5);
}

function visibleTimerCallback(element, observer) {
  delete element.visibleTimeout;
  // Process any pending observations
  processChanges(observer.takeRecords());
  if ('isVisible' in element) {
    delete element.isVisible;
    logImpressionToServer();
    observer.unobserve(element);
  }
}

function processChanges(changes) {
  changes.forEach(function(changeRecord) {
    var element = changeRecord.target;
    element.isVisible = isVisible(changeRecord.boundingClientRect, changeRecord.intersectionRect);
    if ('isVisible' in element) {
      // Transitioned from hidden to visible
      element.visibleTimeout = setTimeout(visibleTimerCallback, 1000, element, observer);
    } else {
      // Transitioned from visible to hidden
      if ('visibleTimeout' in element) {
        clearTimeout(element.visibleTimeout);
        delete element.visibleTimeout;
      }
    }
  });
}

var observer = new IntersectionObserver(
  processChanges,
  { threshold: [0.5] } 
);

var theAd = document.querySelector('#theAd');
observer.observe(theAd);