首页 > 解决方案 > 滚动父div后如何检测哪个子元素可见?

问题描述

我想使用 div 模拟“当前页面”之类的东西(比如 PDF 阅读器)

document.addEventListener("DOMContentLoaded", function(event) {
  var container = document.getElementById("container");
  container.onscroll = function() {
    let position = container.scrollTop;
    let divs = document.querySelectorAll('.page');
    for (div of divs) {
      //???
    }
  }
});
#container {
  width: 400px;
  height: 600px;
  overflow: auto;
}

.page {
  width: 400px;
}

.red {
  background-color: red;
  height: 600px;
}

.blue {
  background-color: blue;
  height: 400px;
}
Current page: <span id="page-counter">1</span>
<div id='container'>
  <div id="div-1" class="page red"></div>
  <div id="div-2" class="page blue"></div>
  <div id="div-3" class="page red"></div>
  <div id="div-4" class="page blue"></div>
</div>

所以,我想知道最好的方法,例如,当第三个 div "出现" 时,将 span page-counter 文本更改为 "3"

像这样的东西:https ://i.imgur.com/rXQ2Bw8.png

在此先感谢塞尔索

标签: javascripthtmlcssscroll

解决方案


由于此问题从未标记 jQuery,因此这是一个纯 Javascript 解决方案,据我所知,它可以模拟您正在寻找的行为。该解决方案计算容器内当前可见的每个子元素的像素数量。如果金额大于或等于容器大小的一半,则假定这是您的访问者正在查看的页面。

function getVisibleHeight(element){
	const container = document.getElementById("container");
	let scrollTop = container.scrollTop;
	let scrollBot = scrollTop + container.clientHeight;
	let containerRect = container.getBoundingClientRect();
	let eleRect = element.getBoundingClientRect();
	let rect = {};
	rect.top = eleRect.top - containerRect.top,
	rect.right = eleRect.right - containerRect.right,
	rect.bottom = eleRect.bottom - containerRect.bottom,
	rect.left = eleRect.left - containerRect.left;
	let eleTop = rect.top + scrollTop;
	let eleBot = eleTop + element.offsetHeight;
	let visibleTop = eleTop < scrollTop ? scrollTop : eleTop;
	let visibleBot = eleBot > scrollBot ? scrollBot : eleBot;

	return visibleBot - visibleTop;
}

document.addEventListener("DOMContentLoaded", function(event) {
	const container = document.getElementById("container");
	const divs = document.querySelectorAll('.page');

	container.addEventListener("scroll", () => {
		for(let i=0; i<divs.length; i++){
			const containerHeight = container.clientHeight;

			// Gets the amount of pixels currently visible within the container
			let visiblePageHeight = getVisibleHeight(divs[i]);

			// If the amount of visible pixels is bigger or equal to half the container size, set page
			if(visiblePageHeight >= containerHeight / 2){
				document.getElementById('page-counter').innerText = i+1;
			}
		}
	}, false);
});
#container {
	width: 400px;
	height: 300px;
	overflow: auto;
}

.page {
	width: 380px;
}

.red {
	background-color: red;
	height: 300px;
}

.blue {
	background-color: blue;
	height: 200px;
}
Current page: <span id="page-counter">1</span>
<div id='container'>
	<div id="div-1" class="page red"></div>
	<div id="div-2" class="page blue"></div>
	<div id="div-3" class="page red"></div>
	<div id="div-4" class="page blue"></div>
</div>


推荐阅读