Reputation: 153
I have done a custom menu with a parallax style. The menu is fixed on top and I want to change the active class for the menu when page scrolls. I have done it by click function so by clicking the menu the active class change to that particular menu. I created this menu with id not 'href="#home"'. Most of the code I find is done by href="#" and nav. I don't want the menu to be one with nav navbar. So can it be done by id?
My codes are below
$("#home-btn").on('click',function() {
$('html, body').animate({
scrollTop : $("#home").offset().top - 10
}, 1000);
$('.main-menu ul li').removeClass('active');
$('#home-btn').parent().addClass('active');
});
$("#service-btn").on('click',function() {
$('html, body').animate({
scrollTop : $("#service").offset().top - 45
}, 1000);
$('.main-menu ul li').removeClass('active');
$('#service-btn').parent().addClass('active');
});
$("#about-btn").on('click',function() {
$('html, body').animate({
scrollTop : $("#about").offset().top - 120
}, 1000);
$('.main-menu ul li').removeClass('active');
$('#about-btn').parent().addClass('active');
});
$("#contact-btn").on('click',function() {
$('html, body').animate({
scrollTop : $("#contact").offset().top - 120
}, 2000);
$('.main-menu ul li').removeClass('active');
$('#contact-btn').parent().addClass('active');
});
.top-adj {
margin-top: 130px;
}
.main-menu {
position: fixed;
top: 0;
left: 0;
right: 0;
background: #f1f1f1;
}
.main-menu ul {
display: flex;
align-items: center;
justify-content: space-between;
}
.main-menu ul li {
display: block;
font-weight: 600;
margin-left: 25px;
}
.main-menu ul li:first-child {
margin-left: 0px;
}
.main-menu ul li a {
color: #000;
display: block;
cursor: pointer;
padding: 25px 10px;
position: relative;
border-bottom: 4px solid;
border-color: transparent;
}
.main-menu ul li a:hover {
text-decoration: none;
}
.main-menu ul li.active a {
padding: 25px 10px;
border-bottom: 4px solid #104377;
}
.section {
width: 100%;
height: 100vh;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="main-menu">
<ul>
<li class="active"><a id="home-btn">Home</a></li>
<li><a id="service-btn">Services</a></li>
<li><a id="about-btn">About</a></li>
<li><a id="contact-btn">Contact</a></li>
</ul>
</div>
<div class="top-adj"></div>
<div class="section" id="home">Home</div>
<div class="section" id="service">Service</div>
<div class="section" id="about">About</div>
<div class="section" id="contact">Contact</div>
Upvotes: 1
Views: 5867
Reputation: 1
This is the edited code of the upper comment.
(function () {
var section = document.querySelectorAll(".section");
var sections = {};
var i = 0;
Array.prototype.forEach.call(section, function (e) {
sections[e.id] = e.offsetTop;
});
window.onscroll = function () {
var scrollPosition = document.documentElement.scrollTop ||
document.body.scrollTop;
for (i in sections) {
if (sections[i] <= scrollPosition) {
$('.nav-item').parent().removeClass('active');
document.querySelector('a[id*=' + i +
']').parentElement.setAttribute('class', 'active');
}
}
};
// Your code
$("#home-btn").on('click', function () {
$('html, body').animate({
scrollTop: $("#home").offset().top
}, 1000);
});
$("#service-btn").on('click', function () {
$('html, body').animate({
scrollTop: $("#service").offset().top
}, 1000);
});
$("#about-btn").on('click', function () {
$('html, body').animate({
scrollTop: $("#about").offset().top
}, 1000);
});
$("#contact-btn").on('click', function () {
$('html, body').animate({
scrollTop: $("#contact").offset().top
}, 2000);
});
})();
.top-adj {
margin-top: 40px;
}
.main-menu {
position: fixed;
top: 0;
left: 0;
right: 0;
background: #f1f1f1;
}
.main-menu ul {
display: flex;
align-items: center;
justify-content: space-between;
}
.main-menu ul li {
display: block;
font-weight: 600;
margin-left: 25px;
}
.main-menu ul li:first-child {
margin-left: 0px;
}
.main-menu ul li a {
color: #000;
display: block;
cursor: pointer;
padding: 4px 10px;
position: relative;
border-bottom: 4px solid;
border-color: transparent;
text-decoration: none;
}
.main-menu ul li a:hover {
text-decoration: none;
}
.main-menu ul li.active a {
padding: 4px 10px;
border-bottom: 4px solid #104377;
}
.section {
width: 100%;
height: 100vh;
padding-top:40px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="main-menu">
<ul>
<li><a class="nav-item" id="home-btn">Home</a></li>
<li><a class="nav-item" id="service-btn">Services</a></li>
<li><a class="nav-item" id="about-btn">About</a></li>
<li><a class="nav-item" id="contact-btn">Contact</a></li>
</ul>
</div>
<div class="top-adj"></div>
<div class="section" id="home">Home</div>
<div class="section" id="service">Service</div>
<div class="section" id="about">About</div>
<div class="section" id="contact">Contact</div>
Upvotes: 0
Reputation: 949
Here we have selected all the elements using the querySelectorAll
method of Vanilla JavaScript.
You can get more idea about Array.prototype.forEach.call()
function here.
We have used window.onscroll
event to perform our scroll spy in which we have matched the top offset of each section with the scroll position of windows and added class based on it.
(function () {
var section = document.querySelectorAll(".section");
var sections = {};
var i = 0;
Array.prototype.forEach.call(section, function (e) {
sections[e.id] = e.offsetTop;
});
window.onscroll = function () {
var scrollPosition = document.documentElement.scrollTop ||
document.body.scrollTop;
for (i in sections) {
if (sections[i] <= scrollPosition) {
document.querySelector('.active').setAttribute('class', ' ');
document.querySelector('a[id*=' + i +
']').parentElement.setAttribute('class', 'active');
}
}
};
// Your code
$("#home-btn").on('click', function () {
$('html, body').animate({
scrollTop: $("#home").offset().top
}, 1000);
});
$("#service-btn").on('click', function () {
$('html, body').animate({
scrollTop: $("#service").offset().top
}, 1000);
});
$("#about-btn").on('click', function () {
$('html, body').animate({
scrollTop: $("#about").offset().top
}, 1000);
});
$("#contact-btn").on('click', function () {
$('html, body').animate({
scrollTop: $("#contact").offset().top
}, 2000);
});
})();
.top-adj {
margin-top: 130px;
}
.main-menu {
position: fixed;
top: 0;
left: 0;
right: 0;
background: #f1f1f1;
}
.main-menu ul {
display: flex;
align-items: center;
justify-content: space-between;
}
.main-menu ul li {
display: block;
font-weight: 600;
margin-left: 25px;
}
.main-menu ul li:first-child {
margin-left: 0px;
}
.main-menu ul li a {
color: #000;
display: block;
cursor: pointer;
padding: 25px 10px;
position: relative;
border-bottom: 4px solid;
border-color: transparent;
text-decoration: none;
}
.main-menu ul li a:hover {
text-decoration: none;
}
.main-menu ul li.active a {
padding: 25px 10px;
border-bottom: 4px solid #104377;
}
.section {
width: 100%;
height: 100vh;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="main-menu">
<ul>
<li class="active"><a id="home-btn">Home</a></li>
<li><a id="service-btn">Services</a></li>
<li><a id="about-btn">About</a></li>
<li><a id="contact-btn">Contact</a></li>
</ul>
</div>
<div class="top-adj"></div>
<div class="section" id="home">Home</div>
<div class="section" id="service">Service</div>
<div class="section" id="about">About</div>
<div class="section" id="contact">Contact</div>
I hope this helps.
Upvotes: 0