简体   繁体   English

在 div 中添加/删除活动 class scrollspy 导航并溢出

[英]add/remove active class scrollspy navigation in div with an overflow

I'm trying to create a navigation menu inside a self scrolling div using html/css/jquery.我正在尝试使用 html/css/jquery 在自滚动 div 中创建导航菜单。 I need the menu items to toggle the active class when the item is in view or reaches the top of the div while scrolling.当项目在视图中或滚动时到达 div 的顶部时,我需要菜单项来切换活动的 class。

basically what i need is exactly this: https://codepen.io/vlrprbttst/pen/LkjZbE?editors=1010 but inside a self scrolling div.基本上我需要的正是这个: https://codepen.io/vlrprbttst/pen/LkjZbE?editors=1010但在一个自滚动的div内。

I created this pen: https://codepen.io/frontend2020/pen/ExWaXVE which kinda works, but the active class triggers too soon and I can't understand why.我创建了这支笔: https://codepen.io/frontend2020/pen/ExWaXVE有点用,但是活动的 class 触发太快了,我不明白为什么。

I am pretty sure the calculation problem is in this bit of code我很确定计算问题出在这段代码中

if (
      refElement.position().top <= scrollPos &&
      refElement.position().top + refElement.height() > scrollPos
    )

i've tried logging scroll position and elements position and everything seems to match but I think i'm off track but i can't understand what I'm missing.我试过记录滚动 position 和元素 position ,一切似乎都匹配,但我认为我偏离了轨道,但我不明白我错过了什么。

A solution or even a hint would be highly appreciated.一个解决方案甚至一个提示将不胜感激。 thank you so much太感谢了

What you're looking for is a scrollspy .您正在寻找的是一个scrollspy

Basically, what you want to do is add an event listener to the document.基本上,您要做的是向文档添加一个事件侦听器。 When the user scrolls, loop through all sections and check whether the element is in viewport.当用户滚动时,循环遍历所有部分并检查元素是否在视口中。 If it is, add the corresponding class to the corresponding nav element.如果是,则将对应的 class 添加到对应的 nav 元素中。 If it isn't, remove that class.如果不是,请删除该 class。

Demonstrated like below:如下所示:

 $(document).ready(function() { function isElementInViewport(el) { if (typeof jQuery === "function" && el instanceof jQuery) { el = el[0]; } var rect = el.getBoundingClientRect(); return ( rect.top >= 0 && rect.left >= 0 && rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && rect.right <= (window.innerWidth || document.documentElement.clientWidth) ); } var sections = $('.section'); $(document).scroll(function() { for (let i = 0; i < sections.length; i++) { let cur = sections[i]; let corresponding = $('li[data-id="' + $(cur).data('for') + '"'); if (isElementInViewport(cur)) { corresponding.addClass('active'); } else { corresponding.removeClass('active'); } } }) })
 .section.first { margin-top: 100px; }.section { height: 500px; border: 1px solid; }.nav { position: fixed; top: 0; }.nav.active { background-color: #ff4a4a; color: white; }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div class="nav"> <ul> <li data-id="1">Section 1</li> <li data-id="2">Section 2</li> <li data-id="3">Section 3</li> </ul> </div> <div class="section first scrollspy-target" data-for="1"> Section 1 </div> <div class="section scrollspy-target" data-for="2"> Section 2 </div> <div class="section scrollspy-target" data-for="3"> Section 3 </div>

Edit: I recommend testing the demo out here .编辑:我建议在 这里测试演示。

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

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