很久之前写过一个插件:jQuery滚动高亮插件:scrollHighlight,关于在滚动网页时同时高亮对应的导航链接节点。今天在CSS-trick上看到一个比较精简的代码,只有8行代码就搞定。
HTML
<script src="//code.jquery.com/jquery-1.11.0.min.js"></script> <div class="nav"> <span id ="menu">☰</span> <ul id="top-menu"> <li><a href="#one" class="links">Menu 1</a></li> <li><a href="#two" class="links">Menu 2</a></li> <li><a href="#three" class="links">Menu 3</a></li> <li><a href="#four" class="links">Menu 4</a></li> <li><a href="#five" class="links">Menu 5</a></li> <li><a href="#six" class="links">Menu 6</a></li> </ul> </div> <div id="wrapper"> <div id="one" class="container"> one </div> <div id="two" class="container"> two </div> <div id="three" class="container"> three </div> <div id="four" class="container"> four </div> <div id="five" class="container"> five </div> <div id="six" class="container"> six </div> </div>
JS代码:附带超详细的代码解释,实际上只有7-8行代码就搞定
$(document).ready(function(){ // $sections incleudes all of the container divs that relate to menu items. var $sections = $('.container'); // The user scrolls $(window).scroll(function(){ // currentScroll is the number of pixels the window has been scrolled var currentScroll = $(this).scrollTop(); // $currentSection is somewhere to place the section we must be looking at var $currentSection // We check the position of each of the divs compared to the windows scroll positon $sections.each(function(){ // divPosition is the position down the page in px of the current section we are testing var divPosition = $(this).offset().top; // If the divPosition is less the the currentScroll position the div we are testing has moved above the window edge. // the -1 is so that it includes the div 1px before the div leave the top of the window. if( divPosition - 1 < currentScroll ){ // We have either read the section or are currently reading the section so we'll call it our current section $currentSection = $(this); // If the next div has also been read or we are currently reading it we will overwrite this value again. This will leave us with the LAST div that passed. } // This is the bit of code that uses the currentSection as its source of ID var id = $currentSection.attr('id'); $('a').removeClass('active'); $("[href=#"+id+"]").addClass('active'); }) }); });
CSS代码就不写了。
直接看演示了:演示
评论里说到不了最后一个,在网上看到一个代码是支持获取滚动最底部的时候,当最后一个列表的元素没有高亮时,此时会移除其它元素的高亮,然后给最后一个元素高亮。
<div id="main"> <div class="container clearfix"> <div id="sidebar"> <div id="nav-anchor"></div> <nav> <ul> <li><a href="#home">Home</a></li> <li><a href="#about">About</a></li> <li><a href="#services">Services</a></li> <li><a href="#blog">Blog</a></li> <li><a href="#contact">Contact</a></li> </ul> </nav> </div><!-- /sidebar --> <div id="content"> <section id="home"> ... </section> <section id="about"> ... </section> <section id="services"> ... </section> <section id="blog"> ... </section> <section id="contact"> ... </section> </div><!-- /#content --> </div><!-- /.container --> </div><!-- /#main -->
JavaScript代码:
$(document).ready(function(){ /** * This part does the "fixed navigation after scroll" functionality * We use the jQuery function scroll() to recalculate our variables as the * page is scrolled/ */ $(window).scroll(function(){ var window_top = $(window).scrollTop() + 12; // the "12" should equal the margin-top value for nav.stick var div_top = $('#nav-anchor').offset().top; if (window_top > div_top) { $('nav').addClass('stick'); } else { $('nav').removeClass('stick'); } }); /** * This part causes smooth scrolling using scrollto.js * We target all a tags inside the nav, and apply the scrollto.js to it. */ $("nav a").click(function(evn){ evn.preventDefault(); $('html,body').scrollTo(this.hash, this.hash); }); /** * This part handles the highlighting functionality. * We use the scroll functionality again, some array creation and * manipulation, class adding and class removing, and conditional testing */ var aChildren = $("nav li").children(); // find the a children of the list items var aArray = []; // create the empty aArray for (var i=0; i < aChildren.length; i++) { var aChild = aChildren[i]; var ahref = $(aChild).attr('href'); aArray.push(ahref); } // this for loop fills the aArray with attribute href values $(window).scroll(function(){ var windowPos = $(window).scrollTop(); // get the offset of the window from the top of page var windowHeight = $(window).height(); // get the height of the window var docHeight = $(document).height(); for (var i=0; i < aArray.length; i++) { var theID = aArray[i]; var divPos = $(theID).offset().top; // get the offset of the div from the top of page var divHeight = $(theID).height(); // get the height of the div in question if (windowPos >= divPos && windowPos < (divPos + divHeight)) { $("a[href='" + theID + "']").addClass("nav-active"); } else { $("a[href='" + theID + "']").removeClass("nav-active"); } } if(windowPos + windowHeight == docHeight) { if (!$("nav li:last-child a").hasClass("nav-active")) { var navActiveCurrent = $(".nav-active").attr("href"); $("a[href='" + navActiveCurrent + "']").removeClass("nav-active"); $("nav li:last-child a").addClass("nav-active"); } } }); });