Files
QIDIStudio/resources/web/model_new/js/navigation.js
2025-12-20 17:45:44 +08:00

82 lines
2.4 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 侧边导航:导轨 + 活动短竖条
(function($){
function positionIndicator(){
var $nav = $('#sideNav');
var $active = $nav.find('.nav-item.active');
if (!$active.length) return;
var top = $active.position().top;
var height = $active.outerHeight();
$nav.find('.indicator').css({ top: top + 'px', height: height + 'px' });
}
function scrollToAnchor($item){
var href = $item.find('a').attr('href');
if (href && href.charAt(0) === '#'){
var $target = $(href);
if ($target.length){
var offset = 70; // 顶部预留,避免顶到视口边缘
$('html,body').animate({ scrollTop: Math.max(0, $target.offset().top - offset) }, 300);
}
}
}
$(function(){
positionIndicator();
$('#sideNav').on('click', '.nav-item', function(e){
e.preventDefault();
var $it = $(this);
$it.addClass('active').siblings('.nav-item').removeClass('active');
positionIndicator();
scrollToAnchor($it);
});
// 滚动联动ScrollSpy
var ticking = false;
function computeActiveByScroll(){
var scrollTop = $(window).scrollTop();
var viewportOffset = 100; // 判定阈值,提前一点触发
var $items = $('#sideNav .nav-item');
var currentId = null;
$items.each(function(){
var href = $(this).find('a').attr('href');
if (!href || href.charAt(0) !== '#') return;
var $sec = $(href);
if (!$sec.length) return;
var top = $sec.offset().top;
if (top <= scrollTop + viewportOffset){
currentId = href;
}
});
if (currentId){
var $cur = $items.filter(function(){
return $(this).find('a').attr('href') === currentId;
}).first();
if ($cur.length && !$cur.hasClass('active')){
$cur.addClass('active').siblings('.nav-item').removeClass('active');
positionIndicator();
} else {
// 位置可能变化,仍然校准指示条
positionIndicator();
}
}
}
function onScroll(){
if (!ticking){
ticking = true;
requestAnimationFrame(function(){
computeActiveByScroll();
ticking = false;
});
}
}
$(window).on('scroll', onScroll);
$(window).on('resize', function(){
positionIndicator();
computeActiveByScroll();
});
// 初始根据当前滚动位置激活一次
computeActiveByScroll();
});
})(jQuery);