I have a navigation menu and some sections. Whenever a specific section is scrolled to, the corresponding navigation element is given the .active
-class through a jQuery function I've made.
What I also want to do is "push" the active child-element of the navigation menu to the front of the menu, while "pushing" the last active element to the back of the menu. See pictures below for clarification:
What I have right now
What I want
As you can see, the item 2
-element is the first element of the menu, while the item 1
-element is the last element of the menu.
What I've tried
The container
-element has the display: flex;
-property, so naturally I tried using the order
-properties on the different navigation elements in my function, but haven't had any success with it.
If anyone has some tips on how to achieve this, I would be grateful as I quite frankly have no idea where to start.
Codepen: https://codepen.io/sigurdmazanti/pen/xxpBxNR
Snippet:
var nav = $(".container");
var sections = $(".section");
$(window).on("scroll", function() {
var cur_pos = $(this).scrollTop();
sections.each(function() {
var top = $(this).offset().top,
bottom = top $(this).outerHeight();
if (cur_pos >= top && cur_pos <= bottom) {
nav.find(".nav").removeClass("active");
nav.find("." $(this)[0].id).addClass("active");
}
});
});
.container {
display: flex;
gap: 30px;
position: sticky;
justify-content: center;
top: 0;
}
.container .nav {
border: 1px solid black;
}
div.active {
background-color: black;
color: white;
}
.section {
height: 350px;
text-align: center;
display: flex;
justify-content: center;
align-items: center;
}
.section.one {
background-color: yellow;
}
.section.two {
background-color: red;
}
.section.three {
background-color: green;
}
.section.four {
background-color: blue;
}
.section.five {
background-color: purple;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<div >
<div >item 1</div>
<div >item 2</div>
<div >item 3</div>
<div >item 4</div>
<div >item 5</div>
</div>
<div id="one">item 1</div>
<div id="two">item 2</div>
<div id="three">item 3</div>
<div id="four">item 4</div>
<div id="five">item 5</div>
CodePudding user response:
This should work nicely for you:
.container > .nav.active {
order: -1;
}
See it working here:
var nav = $(".container");
var sections = $(".section");
$(window).on("scroll", function() {
var cur_pos = $(this).scrollTop();
sections.each(function() {
var top = $(this).offset().top,
bottom = top $(this).outerHeight();
if (cur_pos >= top && cur_pos <= bottom) {
nav.find(".nav").removeClass("active");
nav.find("." $(this)[0].id).addClass("active");
}
});
});
.container {
display: flex;
gap: 30px;
position: sticky;
justify-content: center;
top: 0;
}
.container .nav {
border: 1px solid black;
}
div.active {
background-color: black;
color: white;
}
.section {
height: 350px;
text-align: center;
display: flex;
justify-content: center;
align-items: center;
}
.section.one {
background-color: yellow;
}
.section.two {
background-color: red;
}
.section.three {
background-color: green;
}
.section.four {
background-color: blue;
}
.section.five {
background-color: purple;
}
.container > .nav.active {
order: -1;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<div >
<div >item 1</div>
<div >item 2</div>
<div >item 3</div>
<div >item 4</div>
<div >item 5</div>
</div>
<div id="one">item 1</div>
<div id="two">item 2</div>
<div id="three">item 3</div>
<div id="four">item 4</div>
<div id="five">item 5</div>
CodePudding user response:
On the phone now so hard to edit, but look at the ordering in css . Just change the order style in your script.
Its unclear if you want this to animate though.. a common trick is to copy thw full row and place it afterwards in a div with no overflow. Then on scrolling to the previous or next would quickly rest the bar to mimic endless scrolling..
var nav = $(".container");
var sections = $(".section");
$(window).on("scroll", function() {
var cur_pos = $(this).scrollTop();
sections.each(function() {
var top = $(this).offset().top,
bottom = top $(this).outerHeight();
if (cur_pos >= top && cur_pos <= bottom) {
nav.find(".nav").removeClass("active");
nav.find("." $(this)[0].id).addClass("active");
}
});
});
.container {
display: flex;
gap: 30px;
position: sticky;
justify-content: center;
top: 0;
}
.container .nav {
border: 1px solid black;
}
div.active {
background-color: black;
color: white;
}
.section {
height: 350px;
text-align: center;
display: flex;
justify-content: center;
align-items: center;
}
.section.one {
background-color: yellow;
}
.section.two {
background-color: red;
}
.section.three {
background-color: green;
}
.section.four {
background-color: blue;
}
.section.five {
background-color: purple;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<div >
<div style="order:3" >item 1</div>
<div >item 2</div>
<div style="order:1" >item 3</div>
<div >item 4</div>
<div >item 5</div>
</div>
<div id="one">item 1</div>
<div id="two">item 2</div>
<div id="three">item 3</div>
<div id="four">item 4</div>
<div id="five">item 5</div>