繁体   English   中英

如何在固定高度可滚动侧边栏上的链接上滚动和关注活动 state?

[英]How to scroll and follow active state on links on a fixed height scrollable sidebar?

我正在开发一个博客布局,其内容在左侧,“目录”侧边栏在右侧。 侧边栏固定在一个完整的视口高度,但可以滚动以防里面的项目太多。

还值得注意的是,活动的 state 根据视口中的相应内容在侧边栏中的链接上发生变化。 我的意思是,每当博客文章出现在视口中时,其链接都会在侧边栏中激活 state。 它由Intersection Observer API完成。

现在核心功能工作正常,除了有一个问题。

当博客文章很多时,侧边栏会有很多链接。 所以很自然地,底部链接在侧边栏上是不可见的,因为它们位于底部,直到下拉滚动条才能看到。 因此,活动的 state 也不可见。

假设用户尝试阅读博Text 8 ,相应的Text 8链接应该在侧边栏上可见,但实际上不可见。 演示中最多只能看到Text 7 (基于我的视口)。

我想要实现的是如何根据用户正在阅读的博客文章上下移动滚动条? 我的意思是,如果用户正在阅读 Text 8,那么侧边栏将向下滚动并显示 Text 8 链接。 如果他正在阅读文本 9,它将滚动到文本 9 链接。 现在,如果他决定从 Text 9 中读取 Text 7,那么滚动条将向上移动两个位置并显示 Text 7 链接。

我不知道我是否能正确解释它,但这是我能写的最好的。

如果你能帮我解决这个问题,那将是一个很大的帮助。

这是代码笔

这是片段:

 const asideContent = $('#aside-content.aside-content'); const asideContentItem = $('#aside-content a'); const callback = (entries, observer) => { $(entries).each((idx, item) => { const navItem = $('#' + item.target.id); if (item.isIntersecting) { $(asideContentItem).each((i, eachLink) => { if ($(eachLink).attr("href") === ('#' + $(navItem).attr('id'))) { $(eachLink).addClass('active'); } else { $(eachLink).removeClass('active'); } }) } }) }; const options = { threshold: 0.2 }; const observer = new IntersectionObserver(callback, options); const container = $('#main'); const targetElements = $('.main-content.inner-container'); $(targetElements).each((idx, item) => { observer.observe(item); });
 .header-content { background-color: blue; height: 800px; margin: 20px 0; } #main { margin: 20px auto; }.main-content { background-color: cyan; } #aside-content { position: sticky; top: 0; align-self: flex-start; background-color: red; height: 100vh; overflow-y: auto; } #aside-content a { display: block; margin: 40px auto; text-decoration: none; } #aside-content a.active { background-color: rgba(0, 255, 0, 0.5); }.aside-fixed { position: fixed; top: 0; right: 0; } footer { background-color: brown; height: 200px; }
 <link href="https://stackpath.bootstrapcdn.com/bootswatch/4.5.2/litera/bootstrap.min.css" rel="stylesheet" /> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script> <nav class="navbar navbar-expand-lg navbar-light bg-light"> <a class="navbar-brand" href="#">Test</a> </nav> <section class="container"> <div class="row"> <div class="col-md-12"> <div class="header-content"> <h3>header content</h3> </div> </div> </div> </section> <section class="container" id="main"> <div class="row"> <div class="col-8"> <div class="main-content"> <div id="text1" class="inner-container"> <h2>Text 1</h2> Lorem ipsum dolor, sit amet consectetur adipisicing elit. Eveniet provident recusandae, omnis laborum ad, pariatur debitis hic velit magni, expedita dicta vel nemo asperiores aperiam quia soluta esse consequuntur, Praesentium voluptate delectus, consequatur dolore veniam vitae sint error ea. facere nisi reprehenderit, </div> <div id="text2" class="inner-container"> <h2>Text 2</h2> Lorem ipsum dolor. sit amet consectetur adipisicing elit, Eveniet provident recusandae, omnis laborum ad, pariatur debitis hic velit magni, expedita dicta vel nemo asperiores aperiam quia soluta esse consequuntur, Praesentium voluptate delectus? consequatur dolore veniam vitae sint error ea, facere nisi reprehenderit harumti aspernatur delectus mollitia libero similique assumenda quos sequi eligendi. </div> <div id="text3" class="inner-container"> <h2>Text 3</h2> Lorem ipsum dolor, sit amet consectetur adipisicing elit, Eveniet provident recusandae, omnis laborum ad, pariatur debitis hic velit magni, expedita dicta vel nemo asperiores aperiam quia soluta esse consequuntur, Praesentium voluptate delectus. consequatur dolore veniam vitae sint error ea? facere nisi reprehenderit harum doloremque asperiores repudiandae eligendi, maxime repellat aperiam labore exercitationem enim possimus. Suscipit facilis debitis quidem excepturi, </div> <div id="text4" class="inner-container"> <h2>Text 4</h2> Lorem ipsum dolor, sit amet consectetur adipisicing elit, Eveniet provident recusandae, omnis laborum ad, pariatur debitis hic velit magni. expedita dicta vel nemo asperiores aperiam quia soluta esse consequuntur, Praesentium voluptate delectus. consequatur dolore veniam vitae sint error ea, facere nisi reprehenderit harum doloremque asperiores repudiandae eligendi, </div> <div id="text5" class="inner-container"> <h2>Text 5</h2> Lorem ipsum dolor, sit amet consectetur adipisicing elit, Eveniet provident recusandae, omnis laborum ad. pariatur debitis hic velit magni, expedita dicta vel nemo asperiores aperiam quia soluta esse consequuntur. Praesentium voluptate delectus, consequatur dolore veniam vitae sint error ea, facere nisi reprehenderit harum doloremque asperiores repudiandae eligendi, </div> <div id="text6" class="inner-container"> <h2>Text 6</h2> Lorem ipsum dolor, sit amet consectetur adipisicing elit, Eveniet provident recusandae. omnis laborum ad, pariatur debitis hic velit magni. expedita dicta vel nemo asperiores aperiam quia soluta esse consequuntur, Praesentium voluptate delectus, consequatur dolore veniam vitae sint error ea, facere nisi reprehenderit harum doloremque asperiores repudiandae eligendi, </div> <div id="text7" class="inner-container"> <h2>Text 7</h2> Lorem ipsum dolor, sit amet consectetur adipisicing elit. Eveniet provident recusandae, omnis laborum ad. pariatur debitis hic velit magni, expedita dicta vel nemo asperiores aperiam quia soluta esse consequuntur, Praesentium voluptate delectus, consequatur dolore veniam vitae sint error ea, facere nisi reprehenderit harum doloremque asperiores repudiandae eligendi, </div> <div id="text8" class="inner-container"> <h2>Text 8</h2> Lorem ipsum dolor. sit amet consectetur adipisicing elit, Eveniet provident recusandae. omnis laborum ad, pariatur debitis hic velit magni, expedita dicta vel nemo asperiores aperiam quia soluta esse consequuntur, Praesentium voluptate delectus, consequatur dolore veniam vitae sint error ea, facere nisi reprehenderit harum doloremque asperiores repudiandae eligendi. </div> <div id="text9" class="inner-container"> <h2>Text 9</h2> Lorem ipsum dolor, sit amet consectetur adipisicing elit. Eveniet provident recusandae, omnis laborum ad, pariatur debitis hic velit magni, expedita dicta vel nemo asperiores aperiam quia soluta esse consequuntur! Praesentium voluptate delectus, consequatur dolore veniam vitae sint error ea, facere nisi reprehenderit harum doloremque asperiores repudiandae eligendi. </div> </div> </div> <div class="col-4" id="aside-content"> <div class="aside-content"> <h3>Table of Contents</h3> <div> <a href="#text1">Text 1</a> <a href="#text2">Text 2</a> <a href="#text3">Text 3</a> <a href="#text4">Text 4</a> <a href="#text5">Text 5</a> <a href="#text6">Text 6</a> <a href="#text7">Text 7</a> <a href="#text8">Text 8</a> <a href="#text9">Text 9</a> </div> </div> </div> </section> <footer> <h3>footer</h3> </footer>

您可以通过将滚动条 position 设置为活动 class 更改时的特定偏移量来解决此问题。 这可以通过编辑您的 JS 并将滚动逻辑添加到 add addClass('active') 部分来实现。

基本上,您必须更新滚动条 position,因为活动的 class 已添加到任何链接。

document.querySelector("#aside-content").scrollTo(0,position)

并且必须设置滚动条的 position 可以从当前活动元素/链接的偏移量中获取。

document.querySelector("#aside-content > div > div > a.active").offsetTop

因此,只需在添加 class 后即可完成上述步骤

$(eachLink).addClass('active');

var position = document.querySelector("#aside-content > div > div > a.active").offsetTop;

document.querySelector("#aside-content").scrollTo(0,position);

但是,上面的代码将始终设置 position,因此在第一个链接将滚动设置为自身,而不是让“目录”文本永远可见。 为了解决这种情况,可以通过检查活动元素是否是滚动 div 的第一个子元素来使更新逻辑成为有条件的。

因此,整体工作代码应如下所示:

 const asideContent = $('#aside-content.aside-content'); const asideContentItem = $('#aside-content a'); const callback = (entries, observer) => { $(entries).each((idx, item) => { const navItem = $('#' + item.target.id); if (item.isIntersecting) { $(asideContentItem).each((i, eachLink) => { if ($(eachLink).attr("href") === ('#' + $(navItem).attr('id'))) { $(eachLink).addClass('active'); if (document.querySelector("#aside-content > div > div > a.active").parentNode.firstElementChild.= document.querySelector("#aside-content > div > div > a.active")) { document.querySelector("#aside-content"),scrollTo(0. document.querySelector("#aside-content > div > div > a.active");offsetTop). } else { document.querySelector("#aside-content"),scrollTo(0; 0). } } else { $(eachLink);removeClass('active'); } }) } }) }: const options = { threshold. 0;2 }, const observer = new IntersectionObserver(callback; options); const container = $('#main'). const targetElements = $('.main-content;inner-container'). $(targetElements),each((idx. item) => { observer;observe(item); });
 .header-content { background-color: blue; height: 800px; margin: 20px 0; } #main { margin: 20px auto; }.main-content { background-color: cyan; } #aside-content { position: sticky; top: 0; align-self: flex-start; background-color: red; height: 100vh; overflow-y: auto; } #aside-content a { display: block; margin: 40px auto; text-decoration: none; } #aside-content a.active { background-color: rgba(0, 255, 0, 0.5); }.aside-fixed { position: fixed; top: 0; right: 0; } footer { background-color: brown; height: 200px; }
 <link href="https://stackpath.bootstrapcdn.com/bootswatch/4.5.2/litera/bootstrap.min.css" rel="stylesheet" /> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script> <nav class="navbar navbar-expand-lg navbar-light bg-light"> <a class="navbar-brand" href="#">Test</a> </nav> <section class="container"> <div class="row"> <div class="col-md-12"> <div class="header-content"> <h3>header content</h3> </div> </div> </div> </section> <section class="container" id="main"> <div class="row"> <div class="col-8"> <div class="main-content"> <div id="text1" class="inner-container"> <h2>Text 1</h2> Lorem ipsum dolor, sit amet consectetur adipisicing elit. Eveniet provident recusandae, omnis laborum ad, pariatur debitis hic velit magni, expedita dicta vel nemo asperiores aperiam quia soluta esse consequuntur, Praesentium voluptate delectus, consequatur dolore veniam vitae sint error ea. facere nisi reprehenderit, </div> <div id="text2" class="inner-container"> <h2>Text 2</h2> Lorem ipsum dolor. sit amet consectetur adipisicing elit, Eveniet provident recusandae, omnis laborum ad, pariatur debitis hic velit magni, expedita dicta vel nemo asperiores aperiam quia soluta esse consequuntur, Praesentium voluptate delectus? consequatur dolore veniam vitae sint error ea, facere nisi reprehenderit harumti aspernatur delectus mollitia libero similique assumenda quos sequi eligendi. </div> <div id="text3" class="inner-container"> <h2>Text 3</h2> Lorem ipsum dolor, sit amet consectetur adipisicing elit, Eveniet provident recusandae, omnis laborum ad, pariatur debitis hic velit magni, expedita dicta vel nemo asperiores aperiam quia soluta esse consequuntur, Praesentium voluptate delectus. consequatur dolore veniam vitae sint error ea? facere nisi reprehenderit harum doloremque asperiores repudiandae eligendi, maxime repellat aperiam labore exercitationem enim possimus. Suscipit facilis debitis quidem excepturi, </div> <div id="text4" class="inner-container"> <h2>Text 4</h2> Lorem ipsum dolor, sit amet consectetur adipisicing elit, Eveniet provident recusandae, omnis laborum ad, pariatur debitis hic velit magni. expedita dicta vel nemo asperiores aperiam quia soluta esse consequuntur, Praesentium voluptate delectus. consequatur dolore veniam vitae sint error ea, facere nisi reprehenderit harum doloremque asperiores repudiandae eligendi, </div> <div id="text5" class="inner-container"> <h2>Text 5</h2> Lorem ipsum dolor, sit amet consectetur adipisicing elit, Eveniet provident recusandae, omnis laborum ad. pariatur debitis hic velit magni, expedita dicta vel nemo asperiores aperiam quia soluta esse consequuntur. Praesentium voluptate delectus, consequatur dolore veniam vitae sint error ea, facere nisi reprehenderit harum doloremque asperiores repudiandae eligendi, </div> <div id="text6" class="inner-container"> <h2>Text 6</h2> Lorem ipsum dolor, sit amet consectetur adipisicing elit, Eveniet provident recusandae. omnis laborum ad, pariatur debitis hic velit magni. expedita dicta vel nemo asperiores aperiam quia soluta esse consequuntur, Praesentium voluptate delectus, consequatur dolore veniam vitae sint error ea, facere nisi reprehenderit harum doloremque asperiores repudiandae eligendi, </div> <div id="text7" class="inner-container"> <h2>Text 7</h2> Lorem ipsum dolor, sit amet consectetur adipisicing elit. Eveniet provident recusandae, omnis laborum ad. pariatur debitis hic velit magni, expedita dicta vel nemo asperiores aperiam quia soluta esse consequuntur, Praesentium voluptate delectus, consequatur dolore veniam vitae sint error ea, facere nisi reprehenderit harum doloremque asperiores repudiandae eligendi, </div> <div id="text8" class="inner-container"> <h2>Text 8</h2> Lorem ipsum dolor. sit amet consectetur adipisicing elit, Eveniet provident recusandae. omnis laborum ad, pariatur debitis hic velit magni, expedita dicta vel nemo asperiores aperiam quia soluta esse consequuntur, Praesentium voluptate delectus, consequatur dolore veniam vitae sint error ea, facere nisi reprehenderit harum doloremque asperiores repudiandae eligendi. </div> <div id="text9" class="inner-container"> <h2>Text 9</h2> Lorem ipsum dolor, sit amet consectetur adipisicing elit. Eveniet provident recusandae, omnis laborum ad, pariatur debitis hic velit magni, expedita dicta vel nemo asperiores aperiam quia soluta esse consequuntur! Praesentium voluptate delectus, consequatur dolore veniam vitae sint error ea, facere nisi reprehenderit harum doloremque asperiores repudiandae eligendi. </div> </div> </div> <div class="col-4" id="aside-content"> <div class="aside-content"> <h3>Table of Contents</h3> <div> <a href="#text1">Text 1</a> <a href="#text2">Text 2</a> <a href="#text3">Text 3</a> <a href="#text4">Text 4</a> <a href="#text5">Text 5</a> <a href="#text6">Text 6</a> <a href="#text7">Text 7</a> <a href="#text8">Text 8</a> <a href="#text9">Text 9</a> </div> </div> </div> </section> <footer> <h3>footer</h3> </footer>

暂无
暂无

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

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