css 如何检测滚动父div后哪个子元素是可见的?

t40tm48m  于 2023-01-27  发布在  其他
关注(0)|答案(3)|浏览(183)

我想模拟像"当前页"使用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页计数器文本更改为"3"
大概是这样的https://i.imgur.com/rXQ2Bw8.png
提前感谢Celso

4xrmg8kj

4xrmg8kj1#

因为这个问题从来没有标记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>
ogsagwnx

ogsagwnx2#

这里的一般方法是编写一个函数来确定给定的HTML元素是否在viewport中。您可以在用户滚动时运行检查。请参阅下面的jQuery示例片段。我不一定说这是最好的方法,但它似乎正在工作。开始滚动可以看到ID出现。

function isInViewPort(element) {
  // Function will determine if any part of the element is in the viewport.
  let $el = $("#" + element);
  let windowScrollTop = $(window).scrollTop();
  let windowHeight = $(window).height();
  let windowBottom = windowScrollTop + windowHeight;
  let elementTop = $el.offset().top;
  let elementOuterHeight = $el.outerHeight();
  let elementBottom = elementTop + elementOuterHeight;

  let isAboveViewPort = elementBottom < windowScrollTop;
  let isBelowViewPort = windowBottom < elementTop;

  return !(isAboveViewPort || isBelowViewPort);
}

let currentDiv;

$("#container").on("scroll", function() {
  $("#container").find("div").each(function() {
    if (isInViewPort(this.id) && currentDiv !== this.id) {
      $("#page").html("Current ID is " + this.id)
      currentDiv = this.id;
    }
  });
});
#container {
  overflow: auto;
  height: 300px;
}

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

.blue {
  background-color: blue;
  height: 400px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<span id="page"></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>
g2ieeal7

g2ieeal73#

你可以在jQuery中使用is visible特性,只需要给予每个div一个唯一的ID或者类。

if( $("#uniqueIdHere").is(':visible'))
   $(".page3Selector").addClass('active');

然后要删除活动类,可以将其与else语句配对,以删除非活动div的类。

相关问题