Struggling with a function I created to slide a div horizontally into view in the center of a vertically scrolling page. It seems to work well under normal conditions, but when the page is scrolled quickly, it sometimes fails to complete the horizontal movement. It's particularly troublesome when it stops short of reaching the left-most edge of the browser. Any ideas on how to resolve this issue?
Interested in troubleshooting? Check out the codepen link: https://codepen.io/ThatWerewolfTho/pen/xxRZERv
HTML
<div class="wrapper">
<section id="section1" class="full-screen">
<div class="container">
<div class="container-inner">
<h1>This is a very complicated case Maude. You know, a lotta ins, a lotta outs, lotta what-have-yous. There's a lot of strands to keep in my head, man.</h1>
</div>
</div>
</section>
<section id="section2" class="full-screen side-scroll">
<div class="container">
<div class="container-inner">
<h1>I am not Mr. Lebowski. You're Mr. Lebowski. I’m the Dude! So that’s what you call me. That or, uh His Dudeness, or uh Duder, or El Duderino, if you’re not into the whole brevity thing.</h1>
</div>
</div>
</section>
<section id="section3" class="full-screen">
<div class="container">
<div class="container-inner">
<h1>Saturday, Donny, is Shabbos, the Jewish day of rest. That means I don't work. I don't drive a car. I don't fuckin' ride in a car. I don't handle money. I don't turn on the oven and I sure as shit don't fuckin' roll!</h1>
</div>
<div>
</section>
</div>
CSS
body {
box-sizing: border-box;
color: #fff;
margin: 0;
}
.full-screen {
text-align: center;
}
.container {
height: 100vh;
position: relative;
width: 100vw;
}
.container-inner {
left: 0;
margin: 0;
padding:0 2rem;
position: absolute;
top: 50%;
transform: translateY(-50%);
}
#section1 {
position: fixed;
}
#section1 .container {
background-color: #bd1a54;
}
#section2 .container {
background-color: #c9bfec;
left: 100%;
position: fixed;
top: 0;
translate: transformY(-50%);
}
#section3 .container {
background-color: #35b761;
}
JS
const sideScroll = () => {
const docWidth = document.body.clientWidth
const target = document.getElementById('section2')
const targetChild = target.querySelector('.container')
// Set the horizontal div height to give the illusion of stasis
target.style.height = `${docWidth}px`
targetChild.style.left = `${docWidth}px`
const scrollThis = () => {
// Find the top of the horizontal scrolling div container
let targetRect = target.getBoundingClientRect()
// Compare it against the bottom of the window
// If it's in the viewport, tell the horizontal div that it's cool to come in
const windowBottom = window.innerHeight
let output = false
if (targetRect.top < window.innerHeight) {
output = true
}
return output
}
window.onscroll = scrollThis
const setHorizontalPosition = () => {
const targetRect = target.getBoundingClientRect()
const howMuchScrolled = targetRect.height - targetRect.bottom
const percentageScrolled = (howMuchScrolled / (targetRect.height - window.innerHeight)) * 100
if (scrollThis() === true && percentageScrolled <= 100) {
targetChild.style.left = `${100 - percentageScrolled}%`
}
}
window.onscroll = setHorizontalPosition
}
window.onload = sideScroll