我正在创建一个带有锚链接导航的长页面。向下滚动页面时,导航中的相应链接将突出显示以匹配您所在的部分。
它工作正常,但我在页面上也有一个部分,导航中没有锚链接。问题是,通过添加此部分,它会破坏我的部分顺序,这会破坏正确的选定状态。
这是一个代码示例,向您展示一个示例。 http://codepen.io/anon/pen/jEdKBp - 请注意,当您向下滚动到“新部分”时,导航中的“声明”链接会突出显示,这是错误的!
我需要做什么才能突出显示当前链接?
这是我的代码......
HTML
<nav id="prod-menu">
<div class="wrapper">
<ul>
<li><a href="#features">Features</a></li>
<li><a href="#claims">Claims</a></li>
<li><a href="#guides">Guides</a></li>
<li><a href="#reviews">Reviews</a></li>
<li><a href="#faq">FAQs</a></li>
</ul>
</div>
</nav>
<section class="prod-hero"></section>
<div class="wrapper">
<section class="tile js-panel pad0">
<section id="features" class="prod-panels">
<h2>Features</h2>
</section>
<section class="prod-panels">
<h2>New section</h2>
<p>I do not want this section to appear in the nav</p>
</section>
<section id="claims" class="prod-panels">
<h2>Claims</h2>
</section>
<section id="guides" class="prod-panels">
<h2>Guides</h2>
</section>
<section id="reviews" class="prod-panels">
<h2>Reviews</h2>
</section>
<section id="faq" class="prod-panels">
<h2>FAQs</h2>
</section>
</section>
</div>
的jQuery
var homeH = $( window ).height(),
pH = [];
pH.push("0");
// create array with panel heights
for (var s=1; s<5; s++) {
var po = $(".js-panel section:nth-child("+s+")").position();
pH.push( Math.round(po.top) );
};
$( window ).scroll(function() {
// toggle top menu selection
for (var i=0;i<6;i++) {
if ( $( window ).scrollTop() > pH[i]+900 ) {
$("#prod-menu ul li").removeClass("sel");
$("#prod-menu ul li:nth-child("+(i+1)+")").addClass("sel");
}
};
});
答案 0 :(得分:4)
我已经更改了代码中的一些内容,我希望这样:http://codepen.io/anon/pen/pvmXgK就是您想拥有的内容。
首先,我改变了这一行:
var po = $(".js-panel section:nth-child("+s+")").position();
到
var po = $(".js-panel section.nav-section:eq("+s+")").offset();
并将类nav-section
添加到应该属于导航的所有html部分。
切换功能现在被拆分为两个for循环,但这可能不是必需的。 ;)
所有代码(没有css部分) 的 HTML 强>:
<nav id="prod-menu">
<div class="wrapper">
<ul>
<li><a href="#features">Features</a></li>
<li><a href="#claims">Claims</a></li>
<li><a href="#guides">Guides</a></li>
<li><a href="#reviews">Reviews</a></li>
<li><a href="#faq">FAQs</a></li>
</ul>
</div>
</nav>
<section class="prod-hero"></section>
<div class="wrapper">
<section class="tile js-panel pad0">
<section id="features" class="nav-section prod-panels">
<h2>Features</h2>
</section>
<section class="prod-panels">
<h2>New section</h2>
<p>I do not want this section to appear in the nav</p>
</section>
<section id="claims" class="nav-section prod-panels">
<h2>Claims</h2>
</section>
....
</section>
</div>
<强> JS 强>:
var homeH = $( window ).height(),
pH = [];
var clicked = false;
// create array with panel heights
for (var s=0; s<5; s++) {
var po = $(".js-panel section.nav-section:eq("+s+")").offset();
pH.push( Math.round(po.top) );
};
$( window ).scroll(function() {
if (clicked === true) {
return;
} else if (clicked == "fuzzy") {
clicked = false;
return;
}
// toggle top menu
if ( $( window ).scrollTop() < homeH/2) {
$("#prod-menu ul li").removeClass("sel");
$("#prod-menu").css("top", "-55px");
} else {
$("#prod-menu").css("top", "0");
};
$("#prod-menu ul li").removeClass("sel");
// toggle top menu selection
var st = $( window ).scrollTop();
for (var i=4;i>=0;i--) {
if ( st > pH[i] ) {
$("#prod-menu ul li:eq("+i+")").addClass("sel");
break;
}
};
});
// animating anchor link scrolling
// snippet from css-tricks
// css-tricks.com/snippets/jquery/smooth-scrolling
$("a[href*=#]:not([href=#])").click(function() {
if (location.pathname.replace(/^\//,'') == this.pathname.replace(/^\//,'') && location.hostname == this.hostname) {
var liEle = $(this).parent("li");
var target = $(this.hash);
target = target.length ? target : $('[name=' + this.hash.slice(1) +']');
if (target.length) {
clicked = true;
$('body').animate({
scrollTop: target.offset().top-50
}, 700, function() {
clicked = "fuzzy";
$("#prod-menu ul li").removeClass("sel");
liEle.addClass("sel");
});
return false;
}
}
});
答案 1 :(得分:2)
我已经分叉你的代码笔,试图使用另一种方法
http://codepen.io/anon/pen/myNRzR
var homeH = $( window ).height(),
pH = new Array();
// create array with panel heights
$(".js-panel section").each(function(){
var elm = $(this);
var po = elm.position();
pH.push({
top : Math.round(po.top),
element : elm
});
});
pH.sort(function(a, b) {
if (a.top > b.top)
return -1;
if (a.top < b.top)
return 1;
// a doit être égale à b
return 0;
});
var ord = {
hasScrolled : true,
locked : false
};
var ticker = function(){
if(ord.hasScrolled){
var menu = $("#prod-menu"),
actTop = $( window ).scrollTop(),
level = actTop + menu.height();
ord.locked = true;
ord.hasScrolled = false;
for(var i in pH){
var o = pH[i];
if(level > o.top && level < (o.top + o.element.height())){
menu.css("top", "0");
$("#prod-menu ul li").removeClass("sel");
$("#prod-menu").find("a[href='#"+ o.element.attr("id") +"']").parent().addClass("sel");
break;
}
}
ord.locked = false;
}
}
setInterval(ticker, 250);
$( window ).scroll(function() {
ord.hasScrolled = true && !ord.locked;
// toggle top menu
});
// animating anchor link scrolling
// snippet from css-tricks
// css-tricks.com/snippets/jquery/smooth-scrolling
$("a[href*=#]:not([href=#])").click(function() {
if (location.pathname.replace(/^\//,'') == this.pathname.replace(/^\//,'') && location.hostname == this.hostname) {
var target = $(this.hash);
target = target.length ? target : $('[name=' + this.hash.slice(1) +']');
if (target.length) {
$('html,body').animate({
scrollTop: target.offset().top-50
}, 700);
return false;
}
}
});
使用代码而不是onScrollEvent:它的工作正常。
如果将所有内容包装在插件中会更好。
答案 2 :(得分:2)
我决定对此进行一次尝试。我喜欢在考虑灵活性的情况下处理这样的事情,尽可能地删除硬编码值,并考虑动态页面流。在我的分支中,我不使用你想链接到top-nav的面板上的类,而是使用href和面板ID来利用那些匹配所隐含的链接。
var navPanels = $();
$('#prod-menu a').each(function() {
navPanels = navPanels.add($(this.hash)); // easy array of nav panels according to nav items
});
采用这种方法,您可以简单地添加或减去导航项和面板而无需其他类。此外,如果它们改变高度或移动,因为堆栈中它们上面的另一个元素导致偏移量发生变化,从一开始就有一个offset()。top值的数组在滚动时将不匹配,因此在滚动时检查。然后偏移检查变为:
navPanels.each(function() {
var $p = $(this) // current panel in loop
if ( $( window ).scrollTop() + $('#prod-menu').outerHeight() >= $p.offset().top) {
$("#prod-menu ul li").removeClass("sel");
$('#prod-menu a').filter('[href="#'+$p.attr('id')+'"]').parent().addClass("sel");
}
});
我还考虑了整个脚本中的最高导航高度,以便当该部分滚过可视区域时会突出显示导航项目,该区域从顶部导航下方开始。
这种方法没有做的是删除您不希望在导航中显示的部分的突出显示。相反,它只是在突出显示之前离开导航。
这是完整的JS:
$(function() {
var homeH = $( window ).height(),
navPanels = $();
$('#prod-menu a').each(function() {
navPanels = navPanels.add($(this.hash)); // easy array of nav panels according to nav items
});
$( window ).scroll(function() {
// toggle top menu
if ( $( window ).scrollTop() < homeH/2) {
$("#prod-menu ul li").removeClass("sel");
$("#prod-menu").css("top", ($('#prod-menu').outerHeight()*-1));
}
else {
$("#prod-menu").css("top", "0");
};
// toggle top menu selection
navPanels.each(function() {
var $p = $(this) // current panel in loop
if ( $( window ).scrollTop() + $('#prod-menu').outerHeight() >= $p.offset().top) {
$("#prod-menu ul li").removeClass("sel");
$('#prod-menu a').filter('[href="#'+$p.attr('id')+'"]').parent().addClass("sel");
}
});
});
// animating anchor link scrolling
// snippet from css-tricks
// css-tricks.com/snippets/jquery/smooth-scrolling
$("a[href*=#]:not([href=#])").click(function() {
if (location.pathname.replace(/^\//,'') == this.pathname.replace(/^\//,'') && location.hostname == this.hostname) {
var target = $(this.hash);
target = target.length ? target : $('[name=' + this.hash.slice(1) +']');
if (target.length) {
$('html,body').animate({
scrollTop: target.offset().top-$('#prod-menu').outerHeight()
}, 700);
return false;
}
}
});
});
完整的笔在这里:http://codepen.io/anon/pen/MYNmbb
编辑:我很无聊所以我决定对此进行扩展。如果您希望导航在您滚动到不在导航栏上的部分时不亮,您可以更改&#34;切换顶部菜单选项&#34;功能如下,检查面板底部相对于可视区域:
// toggle top menu selection
navPanels.each(function() {
var $p = $(this) // current panel in loop
var viewTop = $( window ).scrollTop() + $('#prod-menu').outerHeight();
if (viewTop >= $p.offset().top) {
$("#prod-menu ul li").removeClass("sel");
if ($p.offset().top + $p.outerHeight() > viewTop) {
$('#prod-menu a').filter('[href="#'+$p.attr('id')+'"]').parent().addClass("sel");
}
}
});
然后,当您滚动到不在导航中的部分时,在您点击导航中的另一部分之前,不会突出显示任何内容。
同样,完整的笔在此处可见:http://codepen.io/anon/pen/emqWEW