[英]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.