Reputation: 506
I am curious...do the CSS scroll-snap properties have a API (events) that can be hooked into via JavaScript?
I am tinkering with the idea of creating a website that uses scroll-snap to move between 100vh "slides". After each slide is done "scroll-snapping" I would like to trigger an animation.
I am sure there are crafty ways I could check each "slide" to see if it is taking 100% of the viewport, but that sort of sucks. It would be far better to fire a function after the scroll event is complete.
Here is a super simple example:
$(document).ready(function() {
let slideNumber = $('.container > .slide').length;
if (slideNumber > 0) {
$('.container > .slide').each(function() {
$('#dotNav').append('<li><a href="#slide' + $(this).index() + '"></a></li>');
});
}
//DO SOMETHING AFTER SCROLL-SNAP IS COMPLETE.
});
html {
scroll-behavior: smooth;
}
body {
box-sizing: border-box;
scroll-snap-type: y mandatory;
}
.container {
width: 100%;
scroll-snap-type: y mandatory;
position: relative;
.slide {
height: 100vh;
width: 100%;
background: #cccccc;
scroll-snap-align: center;
display: flex;
justify-content: center;
align-items: center;
color: #000000;
&:nth-child(odd) {
background: blue;
h2 {
color: #ffffff;
}
}
h2 {
margin: 0;
font-size: 40px;
text-transform: uppercase;
}
}
ul#dotNav {
position: fixed;
top: 50%;
right: 20px;
list-style: none;
li {
width: 20px;
height: 20px;
margin-bottom: 10px;
cursor: pointer;
a {
display: block;
width: 100%;
height: 100%;
background: #ffffff;
border-radius: 50%;
}
}
li.active {
background: #000000;
}
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<div class="slide" id="slide0">
<h2>Slide 1</h2>
</div>
<div class="slide" id="slide1">
<h2>Slide 2</h2>
</div>
<div class="slide" id="slide2">
<h2>Slide 3</h2>
</div>
<ul id="dotNav">
</ul>
</div>
You can see it working here:
https://codepen.io/trafficdaddy/pen/BMGBBg
Hope someone out there has an answer! :)
Upvotes: 11
Views: 3701
Reputation: 12590
You can do this with an IntersectionObserver
:
document.addEventListener("DOMContentLoaded", () => {
(function scrollSpy() {
const targets = document.querySelectorAll(".section"),
options = {
threshold: 0.5
};
// check if IntersectionObserver is supported
if ("IntersectionObserver" in window) {
(() => {
const inView = target => {
const interSecObs = new IntersectionObserver(entries => {
entries.forEach(entry => {
if(entry.isIntersecting) {
fireyourfunction();
}
});
}, options);
interSecObs.observe(target);
};
targets.forEach(inView);
})();
}
})();
});
Upvotes: 1