In my previous post I asked for help in make some section fixed while scrolling in Vanilla ES6 without frameworks.
Simple HTML structure:
<header class="forewords"><h1>Lorem some</h1>
</header>
<div class="wrapper">
<section class="project" id="item1">this is section 1</section>
<section class="project" id="item2">this is section 2</section>
<section class="project" id="item3">this is section 3</section>
</div>
<footer class="endings"><h1>Lorem something.</h1>
</footer>
This is the core function that does the work:
function pinElement() {
// Reset all styles
projects.forEach((project) => {
document.body.style.paddingTop = 0;
project.classList.remove('fixed');
});
// Get the index of the project that is closest to top
const valueClosestToScrollY = Math.max.apply(Math, projectsOffsetTop.filter((offsetTop) => offsetTop <= window.scrollY));
const idx = projectsOffsetTop.indexOf(valueClosestToScrollY);
// Otherwise, we set the appropriate styles and classes
if (window.scrollY >= projectsOffsetTop[idx]) {
document.body.style.paddingTop = `${projectsHeight[idx]}px`;
projects[idx].classList.add('fixed');
}
};
window.addEventListener('scroll', pinElement);
Right now I'm experiencing two kind of logic issues, the reason why I choose to open another topic.
First of all, every time i scroll first I call the classList.remove('.fixed')
function on everything and suddenly I call classList.add('.fixed')
on the selected element.
This cause a "flickering" effect during all the scroll where the class in removed/added continuosly (having a negative impact on the overall performance I guess).
Is there a way to solve this?
Second issue is that I've added an event listener to update the values of offsets and heights of my elements when somebody resize the windows.
function updateProjectsOffsetTop() {
projectsOffsetTop = projects.map(project => project.offsetTop);
projectsHeight = projects.map(project => project.offsetHeight);
};
window.addEventListener('resize', updateProjectsOffsetTop);
This works fine if I resize the windows before starting scrolling. But if i resize the windows after starting my scroll everything broke.
I can't figure out a way to update the value live and pass them to the scroll function. I would like to solve this code with Vanilla ES6 if it's possible, because I'm trying to learn Javascript starting from that spec.
I know that maybe this are simple issue but I'm here to learn :)
Thanks in advance and find attached the complete JS Fiddle.
const projects = Array.from(document.querySelectorAll('.project'));
let projectsOffsetTop = projects.map(project => project.offsetTop);
let projectsHeight = projects.map(project => project.offsetHeight);
function updateProjectsOffsetTop() {
projectsOffsetTop = projects.map(project => project.offsetTop);
projectsHeight = projects.map(project => project.offsetHeight);
};
function pinElement() {
// Reset all styles
projects.forEach((project) => {
document.body.style.paddingTop = 0;
project.classList.remove('fixed');
});
// Get the index of the project that is closest to top
const valueClosestToScrollY = Math.max.apply(Math, projectsOffsetTop.filter((offsetTop) => offsetTop <= window.scrollY));
const idx = projectsOffsetTop.indexOf(valueClosestToScrollY);
// Otherwise, we set the appropriate styles and classes
if (window.scrollY >= projectsOffsetTop[idx]) {
document.body.style.paddingTop = `${projectsHeight[idx]}px`;
projects[idx].classList.add('fixed');
}
};
window.addEventListener('resize', updateProjectsOffsetTop);
window.addEventListener('scroll', pinElement);
html {
box-sizing: border-box;
}
*, *::before, *::after {
box-sizing: inherit;
margin: 0;
padding: 0;
}
header, footer {
width: 100%;
padding: 10%;
background-color: grey;
position: relative;
}
.project {
width: 100%;
height: 100vh;
position: relative;
display: flex;
justify-content: center;
align-items: center;
top: 0;
}
#item1 {background-color: yellow;}
#item2 {background-color: blue;}
#item3 {background-color: red;}
.fixed {
position: fixed;
}
<header class="forewords"><h1>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Harum soluta ipsam quaerat cupiditate neque, necessitatibus amet nihil perferendis sunt minus! Exercitationem nulla inventore, aut beatae magnam, totam et minus hic.</h1>
</header>
<div class="wrapper">
<section class="project" id="item1">this is section 1</section>
<section class="project" id="item2">this is section 2</section>
<section class="project" id="item3">this is section 3</section>
</div>
<footer class="endings"><h1>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Repudiandae vel, perferendis ullam totam recusandae sed repellendus cum! Molestiae, aut ut sequi eos quidem nam quo est, ad tempora inventore odit.</h1>
</footer>