Reputation: 1
I have an Intersection Observer working for an element on the page, however I want to now apply a completely different animation to another element on the page. I tried creating multiple observers, but it broke. I tried another stackOverflow post where I created an array and tried to use if statements, it broke. I'm still fairly new to JS and learning how to apply logic to different statements, and I'm just stuck not understanding why I can't target multiple elements?
const backgroundTitles = document.querySelectorAll('.section-title span')
const artLoad = document.querySelector('.artwork')
const items = [backgroundTitles, artLoad]
const observer = new IntersectionObserver(entries => {
entries.forEach(entry => {
entry.target.classList.toggle('bgtitle', entry.isIntersecting)
})
console.log(entries)
})
const newObserver = new IntersectionObserver(entries2 => {
entries2.forEach(entry => {
entry.target.classList.toggle('openAnimation', entry.isIntersecting)
})
})
backgroundTitles.forEach(title => {
observer.observe(title)
})
// artLoad.forEach(art => {
// newObserver.observe(art)
// })
I'm sure this is something simple and I'm just not getting it. When I apply the artLoad.forEach... I get an error that artLoad isn't a function? Not sure why.
Upvotes: 0
Views: 4257
Reputation: 1827
This is how I applied a "wow.js" solution using vanilla js on multiple elements on the page...
I actually wanted to animate each element a bit differently but didn't want to write a different JS function for each one because that gets messy quickly.
Please note that:.
I used each element "data-animate" to set which animation to be used.. a bit more flexible in my opinion (and readable) but you can pick a different way to let your JS know which class to toggle...
Some Example HTML
<div class="inview" data-animate="pulse">Animate me...</div>
<div style="height: 100vh;"></div><!--space-->
<div class="inview" data-animate="fadeInUp">Animate me...</div>
<div style="height: 100vh;"></div><!--space-->
<div class="inview" data-animate="fadeInLeft">Animate me...</div>
<div style="height: 100vh;"></div><!--space-->
<div class="inview" data-animate="heartBeat">Animate me...</div>
Example CSS (for animations) - animate.css
.inview { -webkit-animation-duration: 1s; animation-duration: 1s; -webkit-animation-fill-mode: both; animation-fill-mode: both; }
.fadeInUp { -webkit-animation-name: fadeInUp; animation-name: fadeInUp; } @-webkit-keyframes fadeInUp { from { opacity: 0; -webkit-transform: translate3d(0, 20%, 0); transform: translate3d(0, 20%, 0); } to { opacity: 1; -webkit-transform: translate3d(0, 0, 0); transform: translate3d(0, 0, 0); } } @keyframes fadeInUp { from { opacity: 0; -webkit-transform: translate3d(0, 20%, 0); transform: translate3d(0, 20%, 0); } to { opacity: 1; -webkit-transform: translate3d(0, 0, 0); transform: translate3d(0, 0, 0); } }
.fadeInLeft { -webkit-animation-name: fadeInLeft; animation-name: fadeInLeft; } @-webkit-keyframes fadeInLeft { from { opacity: 0; -webkit-transform: translate3d(-30%, 0, 0); transform: translate3d(-30%, 0, 0); } to { opacity: 1; -webkit-transform: translate3d(0, 0, 0); transform: translate3d(0, 0, 0); } } @keyframes fadeInLeft { from { opacity: 0; -webkit-transform: translate3d(-30%, 0, 0); transform: translate3d(-30%, 0, 0); } to { opacity: 1; -webkit-transform: translate3d(0, 0, 0); transform: translate3d(0, 0, 0); } }
.heartBeat { -webkit-animation-name: heartBeat; animation-name: heartBeat; -webkit-animation-duration: 1.3s; animation-duration: 1.3s; -webkit-animation-timing-function: ease-in-out; animation-timing-function: ease-in-out; } @-webkit-keyframes heartBeat { 0% { -webkit-transform: scale(1); transform: scale(1); } 14% { -webkit-transform: scale(1.3); transform: scale(1.3); } 28% { -webkit-transform: scale(1); transform: scale(1); } 42% { -webkit-transform: scale(1.3); transform: scale(1.3); } 70% { -webkit-transform: scale(1); transform: scale(1); } } @keyframes heartBeat { 0% { -webkit-transform: scale(1); transform: scale(1); } 14% { -webkit-transform: scale(1.3); transform: scale(1.3); } 28% { -webkit-transform: scale(1); transform: scale(1); } 42% { -webkit-transform: scale(1.3); transform: scale(1.3); } 70% { -webkit-transform: scale(1); transform: scale(1); } }
.pulse { -webkit-animation-name: pulse; animation-name: pulse; } @-webkit-keyframes pulse { from { -webkit-transform: scale3d(1, 1, 1); transform: scale3d(1, 1, 1); } 50% { -webkit-transform: scale3d(1.05, 1.05, 1.05); transform: scale3d(1.05, 1.05, 1.05); } to { -webkit-transform: scale3d(1, 1, 1); transform: scale3d(1, 1, 1); } } @keyframes pulse { from { -webkit-transform: scale3d(1, 1, 1); transform: scale3d(1, 1, 1); } 50% { -webkit-transform: scale3d(1.05, 1.05, 1.05); transform: scale3d(1.05, 1.05, 1.05); } to { -webkit-transform: scale3d(1, 1, 1); transform: scale3d(1, 1, 1); } }
The Javascript:
const observer = new IntersectionObserver(
entries => {
entries.forEach(entry => {
// get data-animate value
var cls = entry.target.getAttribute('data-animate');
entry.target.classList.toggle(cls, entry.isIntersecting);
});
},
{
root: null, // The element used as the viewport for checking visibility
rootMargin: '0px', // Margin around the root. Can have values similar to the CSS
threshold: .5 // what percentage of the target is visible
}
);
const targets = document.querySelectorAll('.inview');
for (const target of targets) {
observer.observe(target);
}
Upvotes: 4