Я попробовал несколько способов сделать это сейчас, я на 80%, но это все еще не совсем там. У меня есть разделы разных размеров. И моя навигация, в которой я пытаюсь добавить активный класс, когда я нахожусь в соответствующем разделе, показывая, что он активен.
Код имеет тенденцию быть глючным, внутри nav-галереи, у меня есть Галерея кладки и скользкий слайдер. Я не уверен, влияет ли это на это. Но активный класс имеет тенденцию придерживаться галереи, навигации. Каждая секция имеет высоту не менее 100vh.
В соответствии с предложением Cedri c, я попытался с помощью API наблюдателя пересечения . Но у него та же проблема, по крайней мере, в моей реализации, он глючит, и галерея как-то активна, даже когда отсутствует в окне просмотра.
let options = {
root: null,
rootMargin: '0px',
threshold: 1
}
let callback = (entries, observer) => {
console.log("callback called");
entries.forEach(entry => {
console.log("set active for " + entry.target.id);
let sectionId = entry.target.id;
navItems.each(function(){
$(this).removeClass('active');
});
$("a[href='#" + sectionId + "']").addClass('active');
});
};
let observer = new IntersectionObserver(callback, options);
pageSections.each(function () {
let target = document.querySelector("#" + $(this).attr('id'));
observer.observe(target);
});
const navItems = $(".navigation-item");
const pageSections = $(".section-page");
const elementIsInView = el => {
const scroll = window.scrollY || window.pageYOffset
const boundsTop = el.getBoundingClientRect().top + scroll
const viewport = {
top: scroll,
bottom: scroll + window.innerHeight,
}
const bounds = {
top: boundsTop,
bottom: boundsTop + el.clientHeight,
}
return ( bounds.bottom >= viewport.top && bounds.bottom <= viewport.bottom )
|| ( bounds.top <= viewport.bottom && bounds.top >= viewport.top );
}
$(function () {
$(window).scroll(function () {
pageSections.each(function () {
console.log("elements to check " + $(this).attr('id'))
if(elementIsInView($(this)[0])){
console.log("element is in viewport " + $(this).attr('id'))
// this = the section that is visible
let sectionId = $(this).attr('id');
navItems.each(function(){
$(this).removeClass('active');
});
$("a[href='#" + sectionId + "']").addClass('active');
}
})
})
})
.section-page{
height:100vh;
}
.navigation-fixed{
position:fixed;
top:20px;
left:20px;
}
.navigation-fixed ul li a.active{
color:red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<nav class="navigation-fixed">
<ul>
<li>
<a href="#nav-contact" class="navigation-item">CONTACT</a>
</li>
<li>
<a href="#nav-info" class="navigation-item">INFO</a>
</li>
<li>
<a href="#nav-gallery" class="naviation-item">GALLERY</a>
</li>
<li>
<a href="#nav-home" class="navigation-item active">Home</a>
</li>
</ul>
</nav>
<section class="section-page" id="nav-gallery">Content here</section>
<section class="section-page" id="nav-info">Content here</section>
<section class="section-page" id="nav-contact">Content here</section>