JSFiddle - React, Tailwind, and code Playground

by cathead

HTML

<p>
  Lorem ipsum dolor sit amet, consectetur adipisicing elit. Amet, ipsam ipsum laborum facilis veniam quasi officiis magnam suscipit nostrum sequi, sapiente sed quam rem minus voluptates voluptatum ipsa eligendi enim. Quis tempore consequatur dolores ut? Odio ullam dolores dicta. Sunt consectetur aspernatur eveniet similique sed expedita excepturi ipsum beatae doloribus! Voluptas dolorem iure nulla repudiandae illum quisquam culpa consequatur, maiores consequuntur, architecto. Cupiditate quam quibusdam pariatur fugiat! Voluptas aliquam vel maiores earum dolorum nihil dolores porro ad eius provident minus rem at quaerat eligendi error, facilis ducimus commodi.  Lorem ipsum dolor sit amet, consectetur adipisicing elit. Amet, ipsam ipsum laborum facilis veniam quasi officiis magnam suscipit nostrum sequi, sapiente sed quam rem minus voluptates voluptatum ipsa eligendi enim. Quis tempore consequatur dolores ut? Odio ullam dolores dicta. Sunt consectetur aspernatur eveniet similique sed expedita excepturi ipsum beatae doloribus! Voluptas dolorem iure nulla repudiandae illum quisquam culpa consequatur, maiores consequuntur, architecto. Cupiditate quam quibusdam pariatur fugiat! Voluptas aliquam vel maiores earum dolorum nihil dolores porro ad eius provident minus rem at quaerat eligendi error, facilis ducimus commodi.  Lorem ipsum dolor sit amet, consectetur adipisicing elit. Amet, ipsam ipsum laborum facilis veniam quasi officiis magnam suscipit nostrum sequi, sapiente sed quam rem minus voluptates voluptatum ipsa eligendi enim. Quis tempore consequatur dolores ut? Odio ullam dolores dicta. Sunt consectetur aspernatur eveniet similique sed expedita excepturi ipsum beatae doloribus! Voluptas dolorem iure nulla repudiandae illum quisquam culpa consequatur, maiores consequuntur, architecto. Cupiditate quam quibusdam pariatur fugiat! Voluptas aliquam vel maiores earum dolorum nihil dolores porro ad eius provident minus rem at quaerat eligendi error, facilis ducimus...

CSS

body {
  width: 300px;
}
div {
  background-color: orangered;
}

JavaScript

const bannerAds = [...document.querySelectorAll('[data-module="banner-ad"')];

function elementInViewport(el) {
    let top = el.offsetTop;
    let left = el.offsetLeft;
    const width = el.offsetWidth;
    const height = el.offsetHeight;

    while (el.offsetParent) {
        el = el.offsetParent;
        top += el.offsetTop;
        left += el.offsetLeft;
    }

    return (
        top < window.pageYOffset + window.innerHeight &&
        left < window.pageXOffset + window.innerWidth &&
        top + height > window.pageYOffset &&
        left + width > window.pageXOffset
    );
}

function triggerEvent(event, label) {
    console.log('trigger thing');
}

if (bannerAds.length) {

    bannerAds.forEach(bannerAd => {
        const label = bannerAd.getAttribute('label');
        let elementViewed = false;

        if (!elementViewed && elementInViewport(bannerAd)) {
            triggerEvent('view', label);
            elementViewed = true;
        }

        if (!elementViewed) {
            window.addEventListener('scroll', () => {
                if (elementInViewport(bannerAd) && !elementViewed) {
                    triggerEvent('view', label);
                    elementViewed = true;
                }
                // Check if element is not in viewport && elementHasBeenViewed
                if(!elementInViewport(bannerAd) && elementViewed) {
                    // Set elementViewed to false
                    elementViewed = false;
                }
            });
        }

        bannerAd.addEventListener('click', () => {
            triggerEvent('click', label);
        });
    });
}


// orig code

/* if (bannerAds.length) {
    let elementViewed = false;

    bannerAds.forEach(bannerAd => {
        const label = bannerAd.getAttribute('label');

        if (!elementViewed && elementInViewport(bannerAd)) {
            triggerEvent('view', label);
            elementViewed = true;
        }

        if (!elementViewed) {
           ...