jQuery 在窗口滚动时更改导航活动类
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18252374/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Change navigation active class on window scroll
提问by Anna Gabrielyan
i want to create a scroll effect like here http://www.strikingly.com/s/pages/default-ion?demo=ion#1All i need for this moment is to change navigation li class active when the window is scrolling , just change the it using <a href='#about'>
hash target
我想创建一个像这里这样的滚动效果 http://www.strikingly.com/s/pages/default-ion?demo=ion#1 现在我需要的只是在窗口滚动时更改导航 li 类处于活动状态,只需使用<a href='#about'>
哈希目标更改它
回答by Tushar Gupta - curioustushar
Serlite's code is very good but had some bugs.
Serlite的代码非常好,但有一些错误。
- If you scroll down to the end last two
a
elements haveactive
class so both are highlighted.
- 如果向下滚动到最后,最后两个
a
元素具有active
类,因此两者都突出显示。
Solution
解决方案
added $('#menu-center ul li a').removeClass("active");
to remove all previous active class before adding new class in the below code.
添加$('#menu-center ul li a').removeClass("active");
以在以下代码中添加新类之前删除所有以前的活动类。
function onScroll(event){
var scrollPos = $(document).scrollTop();
$('#menu-center a').each(function () {
var currLink = $(this);
var refElement = $(currLink.attr("href"));
if (refElement.position().top <= scrollPos && refElement.position().top + refElement.height() > scrollPos) {
$('#menu-center ul li a').removeClass("active"); //added to remove active class from all a elements
currLink.addClass("active");
}
else{
currLink.removeClass("active");
}
});
}
- If you click on 2nd or greater menu link it makes you scroll to the location but changes active class to previous link.
- 如果您单击第二个或更高的菜单链接,它会使您滚动到该位置,但将活动类更改为上一个链接。
Solution
解决方案
$('html, body').stop().animate({
'scrollTop': $target.offset().top+2
回答by Serlite
Well...not sure if you're still looking for an answer to your question, but I can contribute a suggestion...
好吧...不确定您是否仍在寻找问题的答案,但我可以提供一个建议...
As mentioned, you could use the scrollTop()
method to determine what section is presently in the viewport. Here's a quick function I threw together to determine this, it may not be optimized (I'm not a jQuery expert, sorry), but it seems to work, and should at least put you on the right path to a solution:
如前所述,您可以使用该scrollTop()
方法来确定当前在视口中的部分。这是我拼凑起来的一个快速函数来确定这一点,它可能没有优化(我不是 jQuery 专家,抱歉),但它似乎有效,至少应该让你走上解决方案的正确道路:
function onScroll(event){
var scrollPos = $(document).scrollTop();
$('#menu-center a').each(function () {
var currLink = $(this);
var refElement = $(currLink.attr("href"));
if (refElement.position().top <= scrollPos && refElement.position().top + refElement.height() > scrollPos) {
currLink.addClass("active");
}
else{
currLink.removeClass("active");
}
});
}
This function basically takes the href
of each menu anchor element, and uses it to find the <div>
(or any other element, if you like) with a matching id in the document. After this, it checks to see whether the top of that <div>
is above or at the current scroll position, and its bottom is still below the current scroll position. (Those two conditions being true means that this <div>
is the one currently highest in the viewport, and so should be considered the active section.) The class .active
is then removed/added accordingly. Of course, you can just add/subtract values if you want to offset when a section is considered "active".
此函数基本上采用href
每个菜单锚元素的 ,并使用它来查找<div>
文档中具有匹配 id的(或任何其他元素,如果您愿意)。在此之后,它会检查它的顶部是否<div>
在当前滚动位置的上方或处,其底部是否仍在当前滚动位置的下方。(这两个条件为真意味着这<div>
是当前视口中最高的一个,因此应将其视为活动部分。).active
然后相应地删除/添加该类。当然,如果您想在某个部分被视为“活动”时进行偏移,则可以添加/减去值。
Maybe it's easier just showing what it does, so here's an updated JSFiddlewith this function implemented. It's initially bound using $(document).on("scroll")
- however, note that I also unbound it from the scroll event using $(document).off("scroll")
while the smooth scrolling occurs, so that the section doesn't change until you've reached the destination section (if you click on one of the menu links). After the smooth scrolling occurs, I bind the function again to the scroll event.
也许只是展示它的作用更容易,所以这里有一个更新的 JSFiddle,实现了这个功能。它最初绑定使用$(document).on("scroll")
- 但是,请注意,$(document).off("scroll")
当平滑滚动发生时,我还使用滚动事件将其解除绑定,以便该部分在您到达目标部分之前不会更改(如果您单击菜单链接之一)。平滑滚动发生后,我再次将函数绑定到滚动事件。
Anyways, I hope this is what you were looking for! If it's not, let me know and I'll be happy to help further. (Or I'll try, at least - since as I mentioned, jQuery isn't really my specialty...) Good luck!
无论如何,我希望这就是你要找的!如果不是,请告诉我,我很乐意提供进一步帮助。(或者我会尝试,至少 - 因为正如我所提到的,jQuery 并不是我真正的专长......)祝你好运!
回答by Alexander St?ver
Use $(this).scrollTop();
on your event listener to check what section is in the viewport.
$(this).scrollTop();
在您的事件侦听器上使用以检查视口中的哪个部分。
回答by Borys Zinchuk
hiccup in IE9 so I corrected
在 IE9 中打嗝所以我更正了
$(document).ready(function () {
$(document).on("scroll", onScroll);
//smoothscroll
$('a[href^="#"]').click(function(){
var target = $(this).attr('href');
$('html, body').animate({scrollTop: $(target).offset().top-48}, 500);
return false;
$("#menu a").click(function () {
$("#menu a").removeClass('active');
})
$(this).addClass('active');
var target = this.hash,
menu = target;
$target = $(target);
$('html, body').stop().animate({
'scrollTop': $(target).offset().top-50}, 500, 'swing', function () {
window.location.hash = target;
$(document).on("scroll", onScroll);
});
});
});
function onScroll(event){
var scrollPos = $(document).scrollTop();
j$('#menu a').each(function () {
var currLink = $(this);
var refElement = $(currLink.attr("href"));
if (refElement.position().top-70 <= scrollPos && refElement.position().top-50 + refElement.height() > scrollPos) {
$('#menu ul li a').removeClass("active");
currLink.addClass("active");
}
else{
currLink.removeClass("active");
}
});
}
回答by Arun
I know I am late, but my answer may help the new viewers of this thread. Tushar Gupta's answer is correct. But if there a link in menu that is redirecting to any other page. Tushar Gupta's Answer will throw an error. For Example
我知道我迟到了,但我的回答可能会对这个线程的新观众有所帮助。Tushar Gupta 的回答是正确的。但是如果菜单中有一个链接重定向到任何其他页面。Tushar Gupta 的答案将引发错误。例如
<div class="m1 menu">
<div id="menu-center">
<ul>
<li><a href="#home">Home</a>
</li>
<li><a href="#portfolio">Portfolio</a>
</li>
<li><a href="#about">About</a>
</li>
<li><a href="http://mywebsite.com/blog">Blog</a>
</li>
<li><a href="#contact">Contact</a>
</li>
</ul>
</div>
</div>
<div id="home"></div>
<div id="portfolio"></div>
<div id="about"></div>
<div id="contact"></div>
This will throw an error in console like this. And scrolling will not work for Contact. I Updated Tushar's code to fix that issue.
这将在像控制台抛出错误此。并且滚动不适用于联系人。我更新了 Tushar 的代码来解决这个问题。
function onScroll(event){
var scrollPos = $(document).scrollTop();
$('#menu-center a[href*=#]:not([href=#])').each(function () {
var currLink = $(this);
var refElement = $(currLink.attr("href"));
if (refElement.position().top <= scrollPos && refElement.position().top + refElement.height() > scrollPos) {
$('#menu-center ul li a').removeClass("active"); //added to remove active class from all a elements
currLink.addClass("active");
}
else{
currLink.removeClass("active");
}
});
}