Brian Paskoff
Brian Paskoff

Reputation: 101

Is there a more concise way to write this without a bunch of IF statements?

This script uses intersection observer to look for anything with the class ".anim-target" and then looks to see if it also contains another class ("anim-target-NAME") that tells it which class to add. Then it removes it once it's out of view so it can re-animate again. Is there a more concise way to write it without relying on individual IF statements?

document.addEventListener("DOMContentLoaded", function(event) { 
    observer = new IntersectionObserver(entries => {
        entries.forEach(entry => {
            if (entry.isIntersecting) {
                if (entry.target.classList.contains('anim-target-fadeIn')) {
                    entry.target.classList.add('animated', 'fadeIn');
                }
                if (entry.target.classList.contains('anim-target-fadeInUp')) {
                    entry.target.classList.add('animated', 'fadeInUp');
                }
                if (entry.target.classList.contains('anim-target-bounceIn')) {
                    entry.target.classList.add('animated', 'bounceIn');
                }
                if (entry.target.classList.contains('anim-target-zoomIn')) {
                    entry.target.classList.add('animated', 'zoomIn');
                    entry.target.style.opacity = 1;
                }
            }
            else {
                entry.target.classList.remove('animated', 'fadeIn', 'fadeInUp', 'bounceIn', 'zoomIn');
                entry.target.style.opacity = 0;
            }
        });
    });

    document.querySelectorAll('.anim-target').forEach(image => {
        observer.observe(image);
    });
});

Upvotes: 1

Views: 106

Answers (3)

symlink
symlink

Reputation: 12208

Consider making your code DRYer:

DRY:

let animArr = ["animated"]
let etcl = entry.target.classList

if (etcl.contains("anim-target-fadeIn")) {
   animArr.push(["fadeIn"])
}
if (etcl.contains("anim-target-fadeInUp")) {
  animArr.push(["fadeInUp"])
}
if (etcl.contains("anim-target-bounceIn")) {
  animArr.push(["bounceIn"])
}
if (etcl.contains("anim-target-zoomIn")) {
  animArr.push(["zoomIn"])
  entry.target.style.opacity = 1;
}

etcl.add(...animArr)

Even DRYer:

let animStyles = ["fadeIn","fadeInUp","bounceIn","zoomIn"]
let et = entry.target
let animArr = [] 

animStyles.forEach(style => {
    if(et.classList.contains("anim-target-" + style)){
        animArr = animArr.concat(["animated", style])
    }
}

et.style.opacity = et.classList.contains("anim-target-zoomIn") ? 1 : 0

et.classList.add(...animArr)

Upvotes: 1

Roko C. Buljan
Roko C. Buljan

Reputation: 206669

  • Use just a single class .anim and the desired animation-type class.
  • Use classList.toggle() to toggle/trigger the .animated class:

const animEntry = (ent) => ent.target.classList.toggle('animated', ent.isIntersecting);
const animObserve = () => {
  const observer = new IntersectionObserver(ents => ents.forEach(animEntry));
  document.querySelectorAll('.anim').forEach(el => observer.observe(el));
}
document.addEventListener("DOMContentLoaded", animObserve);
.anim {
  height: 50vh;
  width: 50vh;
  background: #f48024;
  position: relative;
  transition: 1.2s;
  margin: 500px auto;
}

.fadeIn            {opacity:0;}
.fadeIn.animated   {opacity:1;}
.fadeInUp          {opacity:0; transform: translateY(100%); }
.fadeInUp.animated {opacity:1; transform: translateY(0%);}
.zoomIn            {transform: scale(0);}
.zoomIn.animated   {transform: scale(1);}
.rotateCW          {transform: rotate(0deg);}
.rotateCW.animated {transform: rotate(1turn);}
Scroll down...
<div class="anim fadeIn">fadeIn</div>
<div class="anim fadeInUp">fadeInUp</div>
<div class="anim zoomIn fadeIn">zoomIn &amp; fadeIn</div>
<div class="anim rotateCW">rotateCW</div>

Upvotes: 1

T&#226;n
T&#226;n

Reputation: 1

You can replace

if (entry.target.classList.contains('anim-target-fadeIn')) {
    entry.target.classList.add('animated', 'fadeIn');
}
if (entry.target.classList.contains('anim-target-fadeInUp')) {
    entry.target.classList.add('animated', 'fadeInUp');
}
if (entry.target.classList.contains('anim-target-bounceIn')) {
    entry.target.classList.add('animated', 'bounceIn');
}
if (entry.target.classList.contains('anim-target-zoomIn')) {
    entry.target.classList.add('animated', 'zoomIn');
    entry.target.style.opacity = 1;
}

with

var classList = entry.target.classList;

entry.target.classList.add('animated', classList.split('-')[2]);

if (classList.contains('anim-target-zoomIn')) {
    entry.target.style.opacity = 1;
}

Upvotes: 2

Related Questions