繁体   English   中英

如何根据视口和 div 的位置计算我向下滚动 div 的距离?

[英]How do I calculate how far down a div I'm scrolling based on the viewport and the div's position?

我正在构建一个带有系统的博客,以查看访问者当前在文章中的深度,结果以百分比表示。

为了简化一些元素,我跟踪浏览器的底部边框并将其与文章的实际位置进行比较。 页面本身由一个横幅组成,里面有一些项目(标题、元数据等),然后文章本身显示在它下面,但横幅的高度是 60vh。 文章没有设置高度,也没有overflow: scroll属性。

这就是我目前正在做的事情:


const getScrollPercent = () => {
    const prose = document.querySelector<HTMLDivElement>('.prose')

    if (prose) {
        // closest way I got the actual div's top side)
        const proseTop = prose.getBoundingClientRect().top + document.documentElement.scrollTop
        const proseBottom = proseTop + prose.offsetHeight
        const browserBottom = window.scrollY + window.innerHeight

        if (browserBottom < proseTop) {
            return 0
        } else if (browserBottom > proseTop && browserBottom < proseBottom) {
            return (browserBottom / proseBottom) * 100
        } else {
            return 100
        }
    } else {
        return 0
    }
}

但是,行为有点不正常:只要我的视口中没有.prose div,它就会显示 0%,这完全没问题。 然而,在第一个像素,百分比跳到 ~24%,然后一旦到达 div 的底部,它就顺利地以 100% 结束。

我真的不知道是我计算 div 高度的方式不好,还是我计算进度百分比的方式不好。

编辑:HTML结构

(这是一个 Nuxt/VueJS 上下文)


<nav>
<!-- Contains some links-->
</nav>

<main>
  <header>
    <h1>Some article title with a banner in background</h1>
    <div class="meta">
      <!-- Some meta infos (tags, creation date, etc) -->
    </div>
  </header>
  <div class="progress">
    <span class="global">
      {{ getScrollPercent }}%
    </span>
  </div>

  <article>
    <!-- lots of <p> and <h2> to <h6> tags, about 2200px high) !-->
  </article>

</main>

除以 proseBottom 不是执行此操作的正确方法。 如果 proseTop 为 5000,高度为 200,proseBottom 将为 5200。因此,即使浏览器底部为 5000,您也将处于 5000/5200%,这不是您想要的(对吗?)

我想你想要的是

(proseTop - browserBottom) / proseHeight * 100;

这就是您如何计算下方屏幕外的散文字段的百分比

您需要先获取div节点的引用。 在反应中最有可能使用useRef

const yourDivRef = useRef()
//then in your actual div
<div ref={yourDivRef}/>

然后你可以用下面的代码计算你的位置

const node = yourDivRef.current
const offsetHeight = node.scrollHeight // this is about how height your ref div is
const innerHeight = node.clientHeight // this is how height your browser window is
const scrollTop = node.scrollTop // this is where you scroll position at

例如:如果你想得到如果你滚动到底部你做

// check if scroll reach within 5px to the bottom 
 const hasReachedBottom = offsetHeight - (innerHeight + scrollTop) <= 5

正如你所问的:

(innerHeight + scrollTop) / offsetHeight 

应该是你在你的div中的位置percentage

也不要忘记初始化滚动事件侦听器。

useEffect(() => {
// handleScroll should be the place you do all the math. 
    listenTarget.addEventListener('scroll', handleScroll)
    return () => listenTarget.removeEventListener('scroll', handleScroll)
  }, [node])

我希望你发现这是回答你的问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM