Câu trả lời:
Nó được thực hiện bằng cách liên kết với sự kiện cuộn của vùng chứa (thường là cửa sổ).
Ví dụ nhanh:
// Cache selectors
var topMenu = $("#top-menu"),
topMenuHeight = topMenu.outerHeight()+15,
// All list items
menuItems = topMenu.find("a"),
// Anchors corresponding to menu items
scrollItems = menuItems.map(function(){
var item = $($(this).attr("href"));
if (item.length) { return item; }
});
// Bind to scroll
$(window).scroll(function(){
// Get container scroll position
var fromTop = $(this).scrollTop()+topMenuHeight;
// Get id of current scroll item
var cur = scrollItems.map(function(){
if ($(this).offset().top < fromTop)
return this;
});
// Get the id of the current element
cur = cur[cur.length-1];
var id = cur && cur.length ? cur[0].id : "";
// Set/remove active class
menuItems
.parent().removeClass("active")
.end().filter("[href='#"+id+"']").parent().addClass("active");
});
Xem hành động ở trên tại jsFiddle bao gồm cả hoạt ảnh cuộn.
Chỉ cần kiểm tra Mã và Bắn tỉa của tôi và liên kết demo:
// Basice Code keep it
$(document).ready(function () {
$(document).on("scroll", onScroll);
//smoothscroll
$('a[href^="#"]').on('click', function (e) {
e.preventDefault();
$(document).off("scroll");
$('a').each(function () {
$(this).removeClass('active');
})
$(this).addClass('active');
var target = this.hash,
menu = target;
$target = $(target);
$('html, body').stop().animate({
'scrollTop': $target.offset().top+2
}, 500, 'swing', function () {
window.location.hash = target;
$(document).on("scroll", onScroll);
});
});
});
// Use Your Class or ID For Selection
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");
currLink.addClass("active");
}
else{
currLink.removeClass("active");
}
});
}
Chỉ để bổ sung cho câu trả lời của @Marcus Ekwall. Làm như vậy sẽ chỉ nhận được liên kết neo. Và bạn sẽ không gặp vấn đề nếu bạn có sự kết hợp giữa liên kết neo và liên kết thông thường.
jQuery(document).ready(function(jQuery) {
var topMenu = jQuery("#top-menu"),
offset = 40,
topMenuHeight = topMenu.outerHeight()+offset,
// All list items
menuItems = topMenu.find('a[href*="#"]'),
// Anchors corresponding to menu items
scrollItems = menuItems.map(function(){
var href = jQuery(this).attr("href"),
id = href.substring(href.indexOf('#')),
item = jQuery(id);
//console.log(item)
if (item.length) { return item; }
});
// so we can get a fancy scroll animation
menuItems.click(function(e){
var href = jQuery(this).attr("href"),
id = href.substring(href.indexOf('#'));
offsetTop = href === "#" ? 0 : jQuery(id).offset().top-topMenuHeight+1;
jQuery('html, body').stop().animate({
scrollTop: offsetTop
}, 300);
e.preventDefault();
});
// Bind to scroll
jQuery(window).scroll(function(){
// Get container scroll position
var fromTop = jQuery(this).scrollTop()+topMenuHeight;
// Get id of current scroll item
var cur = scrollItems.map(function(){
if (jQuery(this).offset().top < fromTop)
return this;
});
// Get the id of the current element
cur = cur[cur.length-1];
var id = cur && cur.length ? cur[0].id : "";
menuItems.parent().removeClass("active");
if(id){
menuItems.parent().end().filter("[href*='#"+id+"']").parent().addClass("active");
}
})
})
Về cơ bản tôi đã thay thế
menuItems = topMenu.find("a"),
bởi
menuItems = topMenu.find('a[href*="#"]'),
Để khớp tất cả các liên kết với neo ở đâu đó và thay đổi tất cả những gì cần thiết để làm cho nó hoạt động với điều này
Xem nó hoạt động trên jsfiddle
Nếu bạn muốn câu trả lời được chấp nhận hoạt động trong JQuery 3, hãy thay đổi mã như sau:
var scrollItems = menuItems.map(function () {
var id = $(this).attr("href");
try {
var item = $(id);
if (item.length) {
return item;
}
} catch {}
});
Tôi cũng đã thêm một try-catch để ngăn javascript bị lỗi nếu không có phần tử nào theo id đó. Hãy cải thiện nó nhiều hơn nữa;)
menuItems = topMenu.find("a"),
thànhmenuItems = topMenu.find("a").slice(0,4),
, thay thế4
bằng [liên kết trên trang của bạn - 1].