Sunday, May 19, 2024
 Popular · Latest · Hot · Upcoming
102
rated 0 times [  106] [ 4]  / answers: 1 / hits: 7201  / 3 Years ago, fri, november 12, 2021, 12:00:00

I'am trying to makes my navbar moves between sections will I scroll down.


I tried to makes it with JS but I cant makes it work
it is change the active class when I click with event listener but I can't make it work when I scroll


Thanks for any help


here is my js code


let section = document.querySelectorAll('section')
let lists = document.querySelectorAll('.list');
function activeLink(){
lists.forEach((item) =>
item.classList.remove('active'));
this.classList.add('active');
}
lists.forEach((item) =>
item.addEventListener('click',activeLink));

window.onscroll = () =>{
section.forEach(sec =>{
let top = window.scrollY;
let offset = sec.offsetTop;
let height = sec.offsetHeight;
let id = sec.getAttribute('id');

if(top >= offset && top < offset + height){
lists.forEach(sec =>{
activeLink;
})
}
})
};

and this is my html


<nav class="navigation">
<ul>
<li class="list active">
<a href="#home">
<span class="icon">
<ion-icon name="home-outline"></ion-icon>
</span>
<span class="title">Home</span>
</a>
</li>
<li class="list">
<a href="#about">
<span class="icon">
<ion-icon name="person-outline"></ion-icon>
</span>
<span class="title">About Me</span>
</a>
</li>
<li class="list">
<a href="#working">
<span class="icon">
<ion-icon name="newspaper-outline"></ion-icon>
</span>
<span class="title">Working</span>
</a>
</li>
<li class="list">
<a href="#">
<span class="icon">
<ion-icon name="code-slash-outline"></ion-icon>
</span>
<span class="title">Learned</span>
</a>
</li>
<li class="list">
<a href="#contact">
<span class="icon">
<ion-icon name="chatbox-outline"></ion-icon>
</span>
<span class="title">Contact</span>
</a>
</li>
</ul>
</nav>

More From » frontend

 Answers
1

The first problem with your code is that you're not calling the "activeLink" function correctly.


 if(top >= offset && top < offset + height){
lists.forEach(sec =>{
activeLink;
})
}

If you add the parentheses, then it'll work and throw an error due to the "this" keyword which refers to the window object in this case.


To work, in the "onScroll" handler, you can replace your code with this piece:


if (top >= offset && top < offset + height) {
lists.forEach((item) => {
item.classList.remove('active');
if(item.querySelector('a').getAttribute('href') == '#' + id){
item.classList.add('active');
}
});
}

Of course, your aim will be not to duplicate your code. So, we can first select the target like that:


const target = document.querySelector(`[href='#${id}']`).parentElement;
activeLink(target);

Passing it to the "activeLink" function directly will lead you to check the coming parameter if it is the "click event" or the list item and handles both cases. instead, you can edit your handler code like this:


lists.forEach((item) =>
item.addEventListener('click', function(){
activeLink(this);
}));

And this is the "activeLink" function code in the final state:


function activeLink(li) {
lists.forEach((item) => item.classList.remove('active'));
li.classList.add('active');
}

Here is the code snippet for this:




let section = document.querySelectorAll('section');
let lists = document.querySelectorAll('.list');
function activeLink(li) {
lists.forEach((item) => item.classList.remove('active'));
li.classList.add('active');
}
lists.forEach((item) =>
item.addEventListener('click', function(){
activeLink(this);
}));

window.onscroll = () => {
section.forEach(sec => {
let top = window.scrollY;
let offset = sec.offsetTop;
let height = sec.offsetHeight;
let id = sec.getAttribute('id');

if (top >= offset && top < offset + height) {
const target = document.querySelector(`[href='#${id}']`).parentElement;
activeLink(target);
}
})
};

.sec {
height: 500px;
}

nav {
position: fixed;
width: 100%;
top: 0;
left: 0;
z-index: 10;
background-color: #fff;
}

.active a {
color: palevioletred;
}

<nav class=navigation>
<ul>
<li class=list active>
<a href=#home>
<span class=icon>
<ion-icon name=home-outline></ion-icon>
</span>
<span class=title>Home</span>
</a>
</li>
<li class=list>
<a href=#about>
<span class=icon>
<ion-icon name=person-outline></ion-icon>
</span>
<span class=title>About Me</span>
</a>
</li>
<li class=list>
<a href=#working>
<span class=icon>
<ion-icon name=newspaper-outline></ion-icon>
</span>
<span class=title>Working</span>
</a>
</li>
<li class=list>
<a href=#Learned>
<span class=icon>
<ion-icon name=code-slash-outline></ion-icon>
</span>
<span class=title>Learned</span>
</a>
</li>
<li class=list>
<a href=#contact>
<span class=icon>
<ion-icon name=chatbox-outline></ion-icon>
</span>
<span class=title>Contact</span>
</a>
</li>
</ul>
</nav>

<section class=sec style=background-color: beige; id=home></section>
<section class=sec style=background-color: yellow; id=about></section>
<section class=sec style=background-color: orange; id=working></section>
<section class=sec style=background-color: orangered; id=Learned></section>
<section class=sec style=background-color: olive; id=contact></section>




[#689] Saturday, October 30, 2021, 3 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
darennevina

Total Points: 422
Total Questions: 128
Total Answers: 105

Location: Comoros
Member since Tue, Mar 14, 2023
1 Year ago
;