繁体   English   中英

粘滞标题 - 滚动标签

[英]Sticky Header - Scroll with Tabs

我的粘性标题的行为有问题。

期望的行为:

a)滚动到.nav底部到达section顶部的位置将active类添加到选项卡,它将保持active直到.nav到达下一部分的顶部。

b)单击相应部分的.tab始终导航到该部分的顶部,并将active类添加到选项卡。

因此,无论是通过滚动还是单击,都会始终保持选项卡的active状态,直到.nav进入下section ,在这种情况下, active状态将转到该部分的选项卡等。

测试问题:

1)中途向下滚动Option Two.tabactive状态丢失。

2)使用scrollTop滚动到.container的顶部而不是所选section的顶部。

 class StickyNavigation { constructor() { this.currentId = null; this.currentTab = null; let self = this; $(".tab").click(function() { self.onTabClick(event, $(this)); }); $(".container").scroll(() => { this.onScroll(); }); $(".container").resize(() => { this.onResize(); }); } /*Scrolls down to Tab selection*/ onTabClick(event, element) { event.preventDefault(); let scrollTop = $(element.attr("href")).offset().top; if (!$(".nav").hasClass("nav--top")) { scrollTop = scrollTop; } $(".container").animate({ scrollTop: scrollTop }, 600); } onScroll() { this.navPosition(); this.tabAnimation(); } navPosition() { let offset = $(".sticky").offset().top + $(".sticky").height(); if ($(".container").scrollTop() > offset) { $(".nav").addClass("nav--top"); } else { $(".nav").removeClass("nav--top"); } } tabAnimation() { $("section").each(function() { var actual = $(this), actualHeight = actual.height(), actualAnchor = $(".sticky").find('a[href="#' + actual.attr("id") + '"]'); if ( actual.offset().top <= $(".container").scrollTop() && actual.offset().top + actualHeight > $(".container").scrollTop() ) { actualAnchor.addClass("active"); } else { actualAnchor.removeClass("active"); } }); } } new StickyNavigation(); 
 body { position: fixed; display: flex; flex-direction: column; top: 0; bottom: 0; left: 0; right: 0; overflow: hidden; } section { height: 600px; border: 2px solid white; background: blue; } section:nth-child(2) { background: red; } .container { flex: 1; display: flex; position: relative; flex-direction: column; overflow: auto; } .long { height: 1200px; } .header { height: 75px; background: green; } .hero { background: silver; flex: 0; border: 1px solid; } .nav { background: white; width: 100%; display: flex; justify-content: center; align-items: center; position: relative; } .nav--top { position: fixed; top: 75px; } .sticky { background: white; display: flex; flex-direction: row; flex-wrap: wrap; position: relative; } .tab { padding: 30px 45px; position: relative; } .tab.active { background: #6567c5; color: white; } 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div class="header"> <h1>Header</h1> </div> <div class="container"> <div class="hero"> <h1>Hero</h1> </div> <div class="sticky"> <nav role="navigation" class="nav"> <a class="tab" href="#One">Option One</a> <a class="tab" href="#Two">Option Two</a> </nav> </div> <div class="main"> <section id="One"> </section> <section class="long" id="Two"> </section> </div> </div> </div> 

您的部分滚动到顶部的原因是由于添加和删除粘性元素而导致的位置更改。 使用包装代替粘性以始终占据粘性元素的高度,无论它是否存在。

 class StickyNavigation { constructor() { this.currentId = null; this.currentTab = null; this.setup(); this.onResize(); let self = this; $(".tab").click(function(event) { self.onTabClick(event, $(this)); }); $(".container").scroll(() => { this.onScroll(); }); $(window).resize(() => { this.onResize(); }); } setup() { this.$sticky = $('.sticky'); window.stk = this.$sticky; this.$stickyWrap = $('<div>').insertAfter(this.$sticky); this.$sticky.appendTo(this.$stickyWrap); } /*Scrolls down to Tab selection*/ onTabClick(event, element) { event.preventDefault(); let $targetElement = $(element.attr("href")); let positionTop = $targetElement.position().top; let scrollTop = $('.container').scrollTop(); $(".container").animate({ scrollTop: scrollTop - this.stickyOuterHeight + positionTop }, 600); } onScroll() { this.navPosition(); this.tabAnimation(); } onResize() { this.stickyOuterHeight = this.$sticky.outerHeight(); this.$sticky.width(this.$stickyWrap.width()); this.$stickyWrap.css('minHeight', this.stickyOuterHeight); } navPosition() { if (this.$stickyWrap.position().top < 0) { this.$sticky.addClass("fixed"); } else { this.$sticky.removeClass("fixed"); } } tabAnimation() { let desiredSpace = this.stickyOuterHeight + 10; $("section").each(function() { let actual = $(this), actualHeight = actual.height(), actualAnchor = $(".sticky").find('a[href="#' + actual.attr("id") + '"]'); let actualTop = actual.position().top; let actualBottom = actualTop + actualHeight; if (actualTop < desiredSpace && actualBottom > desiredSpace) { actualAnchor.addClass("active"); } else { actualAnchor.removeClass("active"); } }); } } $(function() { new StickyNavigation(); }); 
 body { position: fixed; display: flex; flex-direction: column; top: 0; bottom: 0; left: 0; right: 0; overflow: hidden; } section { height: 600px; border: 2px solid white; background: blue; } section:nth-child(2) { background: red; } .container { flex: 1; display: flex; position: relative; flex-direction: column; overflow: auto; } .long { height: 1200px; } .header { height: 75px; background: green; } .hero { background: silver; flex: 0; border: 1px solid; } .nav { background: white; width: 100%; display: flex; justify-content: center; align-items: center; position: relative; } .sticky { display: flex; flex-direction: row; flex-wrap: wrap; } .sticky.fixed { position: fixed; top: 83px; } .tab { padding: 30px 45px; position: relative; } .tab.active { background: #6567c5; color: white; } 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div class="header"> <h1>Header</h1> </div> <div class="container"> <div class="hero"> <h1>Hero</h1> </div> <div class="sticky"> <nav role="navigation" class="nav"> <a class="tab" href="#One">Option One</a> <a class="tab" href="#Two">Option Two</a> </nav> </div> <div class="main"> <section id="One"> Content One </section> <section class="long" id="Two"> Content Two </section> </div> </div> 

暂无
暂无

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

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