简体   繁体   English

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

[英]How detect which child element is visible after scrolling the parent div?

I would like to emulate something like "current page" using divs (like a PDF reader)我想使用 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>

So, I would like to know the best way to, for example, change span page-counter text to "3" when the third div "appears" .因此,我想知道最好的方法,例如,在第三个 div "appears" 时将 span page-counter text 更改为 "3"

Something like this: https://i.imgur.com/rXQ2Bw8.png像这样: https://i.imgur.com/rXQ2Bw8.png

Thanks in advance Celso在此先感谢塞尔索

Since this question never tagged jQuery, here's a pure Javascript solution that simulates the behavior you're looking for to the best of my knowledge.由于此问题从未标记为 jQuery,因此这里有一个纯 Javascript 解决方案,据我所知模拟您正在寻找的行为。 The solution calculates the amount of pixels of each child element currently visible within the container.该解决方案计算容器中当前可见的每个子元素的像素数量。 If the amount is bigger or equal to half the size of the container, it assumes this is the page your visitor is looking at.如果数量大于或等于容器大小的一半,则假定这是您的访问者正在查看的页面。

 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>

The general approach here would be to write a function that determines if a given HTML element is in the viewport.这里的一般方法是编写一个 function 来确定给定的 HTML 元素是否在视口中。 You could run the check as the user scrolls.您可以在用户滚动时运行检查。 See the snippet below for an example with jQuery. I'm not necessarily saying this is the best way to do this, but it seems to be working.有关 jQuery 的示例,请参阅下面的代码段。我不一定说这是执行此操作的最佳方法,但它似乎有效。 Start scrolling to see the IDs appear.开始滚动以查看出现的 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>

you can use the is visible feature in jQuery. Just give each div a unique ID or class.您可以使用 jQuery 中的可见功能。只需给每个 div 一个唯一的 ID 或 class。

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

and then to remove the active class you could pair it up with an else statement to remove the class of the inactive div.然后要删除活动的 class,您可以将其与 else 语句配对以删除非活动 div 的 class。

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

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