I'm trying to reach the effect similar to https://www.apple.com/iphone-13/ I.e. when user scrolls and reaches a section with slider, slider sticks to the top of the page, scrolling stops in favor of switching slides. When all the slides have been shown, scrolling continues. How can I utilize mousewheel event to stop scrolling and start switching slides instead upon fixing the element? Thanks!
const container = document.querySelector('.slider');
const slides = document.querySelectorAll('.slide');
window.addEventListener('scroll', () => {
const scrollFromTop = window.pageYOffset
if(scrollFromTop <= container.offsetTop) {
container.classList.add('fixed')
/*slides.forEach(element => {
element.classList.remove('active')
})
for(let i = 0; slides.length > i; i++) {
slides[i].classList.add('active');
}*/
}
})
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
section {
width: 100%;
height: 500px;
}
section:nth-child(odd) {
background-color: #666;
}
section.slider {
background-color: #e03c0b;
display: flex;
justify-content: center;
align-items: center;
}
.slide {
display: none;
text-align: center;
width: 50%;
height: 200px;
background-color: #888;
}
.slide.active {
display: block;
}
.fixed {
position: fixed;
top: 0;
}
<section></section>
<section></section>
<section></section>
<section class="slider">
<div class="slide active">Slide 1</div>
<div class="slide">Slide 2</div>
<div class="slide">Slide 3</div>
</section>
<section></section>
<section></section>
If what you are asking for is to switch slides by scrolling then you can add a sticky div inside a container and use javascript to translate the slide container on scroll. Note: there will have to be some bugs worked out as I just whipped this up quick but it should give you an idea of the concept and get you started.
Something like the following:
const container = document.querySelector('.slide-container')
const slides = document.querySelector('.slides')
const containerRect = container.getBoundingClientRect()
const slideRect = slides.getBoundingClientRect()
const containerTop = containerRect.top
const containerHeight = containerRect.height
const slideWidth = slideRect.width
const scrollDistance = containerHeight - window.innerHeight
const slideDistance = slideWidth - window.innerWidth
const getProgress = (start, distance, scroll) => {
return Math.min(1, Math.max(0, (scroll - start) / distance))
}
const handleScroll = () => {
const scrollPos = window.scrollY
const progress = getProgress(containerTop, scrollDistance, scrollPos)
slides.style.transform = `translateX(-${slideDistance * progress}px)`
}
window.addEventListener('scroll', handleScroll)
*{
box-sizing: border-box;
}
body,html{
padding: 0;
margin: 0;
}
.slide-container{
height: 400vh;
width: 100%;
}
.sticky-container{
position:sticky;
top: 0;
height: 100vh;
width: 100%;
overflow:hidden;
}
.slides{
height: 100vh;
width: 400vw;
display:flex;
border: 5px dashed green;
}
.slide{
flex: 1;
margin: 20px;
background: blue;
}
<div style="height: 400px">Scroll Down</div>
<div class="slide-container">
<div class="sticky-container">
<div class="slides">
<div class="slide"></div>
<div class="slide"></div>
<div class="slide"></div>
<div class="slide"></div>
</div>
</div>
</div>
<div style="height: 400px"></div>