Scroll a web page using Javascript whose scroll triggers at the middle of page

Viewed 323

I have encountered some websites which has footer at the bottom and scroll actually happens when I scroll to the area above footer.

To automatically scroll those pages, but the problem with my code currently is it goes at the bottom of the page, where I directly reach footer and hence the scroll trigger which is present just above the footer does not gets triggered.

Is there any way to achieve the same?

This is what I have tried currently which I am executing from the console:

(function() {
    var intervalObj = null;
    var retry = 0;
    var clickHandler = function() { 
        console.log("Clicked; stopping autoscroll");
        clearInterval(intervalObj);
        document.body.removeEventListener("click", clickHandler);
    }
    function scrollDown() { 
        var scrollHeight = document.body.scrollHeight,
            scrollTop = document.body.scrollTop,
            innerHeight = window.innerHeight,
            difference = (scrollHeight - scrollTop) - innerHeight

        if (difference > 0) { 
            window.scrollBy(0, difference);
            if (retry > 0) { 
                retry = 0;
            }
            console.log("scrolling down more");
        } else {
            if (retry >= 3) {
                console.log("reached bottom of page; stopping");
                clearInterval(intervalObj);
                document.body.removeEventListener("click", clickHandler);
            } else {
                console.log("[apparenty] hit bottom of page; retrying: " + (retry + 1));
                retry++;
            }
        }
    }

    document.body.addEventListener("click", clickHandler);

    intervalObj = setInterval(scrollDown, 1000);

})()

There are many websites that has this feature, to test the same one of the website which you can try is

https://www.zomato.com/bangalore/indiranagar-restaurants

Note : The question similar to this does not answer how to scroll at some mid point of page instead it takes me directly to the footer, so this is not a duplicate

2 Answers

Logic is to retain to the middle of the Scroller unless the page is completely loaded. We can tweak the code a little to achieve the last position of scroller. Try this:

 var scrollHeight = 0,
    newScrollHeight;
  do {
    window.scrollTo(0, document.body.scrollHeight / 2);
    newScrollHeight = document.body.scrollHeight / 2;
    if (newScrollHeight == scrollHeight) {
      break;
    } else {
      scrollHeight = newScrollHeight;
    }
  } while (true);

Although Kumar Rishabh has already answered your question, I have another solution for this situation.

Set the domain to detect if the user scrolls to the domain. The effect just like the website you povider . https://www.zomato.com/bangalore/indiranagar-restaurants

I do some simple example for you with pure Javascript.

Fragment core code:

      // Here is domain to detect if user scroll into.
      if (
        triggerDomain.getBoundingClientRect().top < window.innerHeight &&
        triggerDomain.getBoundingClientRect().bottom > 0
      ) {
        if (getMore === false) {
          getMore = true
          // Do something you want here ....
          console.info('got more !!')

Full code sample, check code snippet:

const rootElement = document.getElementById("rootDiv");
const triggerDomain = document.getElementById("triggerDomain");

let getMore = false;

function detectScrollIntoDomain() {
  // Here is domain to detect if user scroll into.
  if (
    triggerDomain.getBoundingClientRect().top < window.innerHeight &&
    triggerDomain.getBoundingClientRect().bottom > 0
  ) {
    if (getMore === false) {
      getMore = true;
      // Do something you want here ....
      console.info("got more !!");
      setTimeout(() => {
        let currentScrollTop = rootElement.scrollTop;
        for (let i = 0; i < 15; i++) {
          let r = Math.floor(Math.random() * 255);
          let g = Math.floor(Math.random() * 255);
          let b = Math.floor(Math.random() * 255);
          const contentElement = document.getElementById("content");
          const card = document.createElement("div");
          card.className = "contentCard";
          card.style.backgroundColor = `rgba(${r}, ${g}, ${b})`;
          contentElement.appendChild(card);
        }
        rootElement.scrollTo(0, currentScrollTop);
        // Don't forget to set flag to `false`.
        getMore = false;
      }, 200);
    }
  }
}

rootElement.addEventListener("scroll", detectScrollIntoDomain, {
  passive: true
});
html,
body {
  position: relative;
  font-family: sans-serif;
  padding: 0;
  margin: 0;
  height: 100%;
  width: 100%;
}

h1,
h2 {
  margin: 0;
  color: aliceblue;
}

#rootDiv {
  position: relative;
  overflow: auto;
  height: 100%;
  width: 100%;
}

#header {
  height: 200px;
  background-color: rgb(112, 112, 112);
}

#content {
  display: flex;
  flex-wrap: wrap;
  position: relative;
  height: fit-content;
  background-color: rgb(136, 136, 136);
}

#content div:first-child {
  height: 600px;
  width: 100%;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
}

#triggerDomain {
  position: absolute;
  bottom: 0px;
  outline: 1px dashed rgb(3, 25, 119);
  height: 500px;
  width: 100%;
  background: repeating-linear-gradient(
    135deg,
    rgba(46, 45, 45, 0.3) 0,
    rgba(46, 45, 45, 0.3) 10px,
    rgba(136, 136, 136, 0.3) 10px,
    rgba(136, 136, 136, 0.3) 20px
  );
}

#footer {
  height: 180%;
  background-color: rgb(112, 112, 112);
}

.contentCard {
  width: 180px;
  height: 180px;
  margin: 12px;
  border-radius: 8px;
  background-color: aquamarine;
}
<!DOCTYPE html>
<html>
  <head>
    <title>Parcel Sandbox</title>
    <meta charset="UTF-8" />
    <link rel="stylesheet" type="text/css" href="./src/styles.css"
  </head>

  <body>
    <div id="rootDiv">
      <div id="header">
        <h1>Header</h1>
      </div>
      <div id="content">
        <div>
          <h2>Content</h2>
          <h2>Scroll down to get more cards.</h2>
        </div>
        <div id="triggerDomain">
          <h2>Trigger domain</h2>
        </div>
      </div>
      <div id="footer">
        <h2>Footer</h2>
      </div>
    </div>
    <script src="src/index.js"></script>
  </body>
</html>

Hope to help you !

Related