使用 Javascript 滚动网页,其滚动在页面中间触发

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

我遇到过一些底部有页脚的网站,当我滚动到页脚上方的区域时,滚动实际上发生了。

要自动滚动这些页面,但我的代码目前的问题是它位于页面底部,我直接到达页脚,因此不会触发位于页脚上方的滚动触发器。

有什么方法可以达到同样的目的吗?

这是我目前从控制台执行的尝试:

(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);

})()

有很多网站有这个功能,要测试同一个网站你可以试试

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

注意:与此类似的问题没有回答如何在页面的某个中间点滚动,而是直接将我带到页脚,所以这不是重复的

逻辑是保留到Scroller中间,除非页面完全加载。我们可以稍微调整代码以获得滚动条的最后位置。试试这个:

 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);

虽然Kumar Rishabh已经回答了你的问题,但对于这种情况,我还有另一种解决方案。

设置域以检测用户是否滚动到域。 效果就像您提供的网站一样。 https://www.zomato.com/bangalore/indiranagar-restaurants

我用纯Javascript为你做了一些简单的例子。

片段核心代码:

      // 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 !!')

完整代码示例,检查代码片段:

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>

希望能帮到你!