Hide Anchor Ads When Scrolling To The Bottom
Adam C. |

I used to have Anchor Ads turned on one of my websites, but I did not like the way it worked. It pushed the page down when the Anchor Ads were shown on the top and pushed the page up when the Anchor Ads were shown on the bottom.  And when you clicked the dismissal (close) button, it left a blank space. So I turned it off.

Photo by CHUTTERSNAP on Unsplash

A few days ago,  I saw the Anchor Ads were on my website again and realized that Google was trying to do some experiment on my website, so 50% of traffic would see the Anchor Ads. This time, they are overlays, so no page layout shift, i.e., no more Cumulative Layout Shift(CLS.) A day later, Google said:

“Good news. The recent experiments below showed positive results and we have applied these changes to your account.”

So it's good, and I decided to keep it, but there is one thing that bugs me. Google removes the dismissal button from the Anchor Ads, so the Ads stay on the page bottom and overlay the footer beneath.  Although the content on the Footer, like some social links, about me, etc. is not very important, I still want users to be able to see them. 

I don't find the option to turn on the dismissal (close) button, but figured out the way to fix this by using some custom Javascript.

I found out that the class name of the Anchor ads contains “adsbygoogle-noablate”, so the idea is to set the elm.style.display to be “none” when the page is scrolled to the bottom. 

Googling “how to detect the page scrolled to the bottom”, you may find this solution:

window.onscroll = function(ev) {
    if ((window.innerHeight + window.scrollY) >= document.body.offsetHeight) {
        // you're at the bottom of the page
    }
};

But it does not work on my page, I think it's because my page has HTML/body set to 100%.

 Does not work when html/body elements are set to 100% (so that the body fills the entire viewport height)

– Grodriguez

So I have to use a different trick by checking if the Footer div is in the viewport.

function isInViewport(el) {
  const rect = el.getBoundingClientRect();
  return (
    Math.floor(rect.bottom) - 200 <=
      (window.innerHeight || document.documentElement.clientHeight)
  );
}

The code is modified from the JS Tutorial. Somehow in my case, rect.bottom is decimal, and always great than window.innerHeight. So I have to use Math.floor()to remove the decimal and make it equal to window.innerHeightwhen the Footer element is shown. I subtract it by 200 on purpose to make it happen earlier, i.e., when the Footer is still 200px below the viewport, I call it in the viewport. (so I can hide the Anchor Ads slightly before the page is scrolled to the bottom.)

I use React, and the component is like the below:

import React, { useState, useEffect } from "react";
import { Icon } from "semantic-ui-react";

function isInViewport(el) {
  const rect = el.getBoundingClientRect();
  return (
    Math.floor(rect.bottom) - 200 <=
      (window.innerHeight || document.documentElement.clientHeight)
  );
}

const AutoHideAnchorAds = () => {
  const [showAd, setShowAd] = useState(true);

  useEffect(() => {
    window.addEventListener("scroll", checkScrollTop);
    return function cleanup() {
      window.removeEventListener("scroll", checkScrollTop);
    };
  });

  const checkScrollTop = () => {
    if (!showAd && !isInViewport(document.querySelector("#deniFooter"))) {
      // console.log("showAd"); // show ads when it was not
      if (document.getElementsByClassName("adsbygoogle-noablate").length > 0)
        document.getElementsByClassName(
          "adsbygoogle-noablate"
        )[0].style.display = "block";
      setShowAd(true);
    } else if (showAd && isInViewport(document.querySelector("#deniFooter"))) {
      // console.log("hideAd"); // hide ads when hit the bottom
      if (document.getElementsByClassName("adsbygoogle-noablate").length > 0)
        document.getElementsByClassName(
          "adsbygoogle-noablate"
        )[0].style.display = "none";
      setShowAd(false);
    }
  };
  return null; //this component does not render anything, you can incorporate it into other component if you want.
};

export default AutoHideAnchorAds;

To see how it works, check it out at https://swimstandards.com/. (Remember to turn off Ad Blocker :-))