简体   繁体   中英

Vanilla JavaScript running CSS animation on div scroll into view not working

I'm trying to run a CSS Animation when a div enters the visible screen. However, I'm noticing the animations are playing when the page loads no matter what.

I've googled the problem, I've messed with the code, nothing seems to be giving me the right results.

JavaScript

    var animateHTML = function() {
    var elems;
    var windowHeight;
    function init() {
      elems = document.querySelectorAll('.animatemeplz');
      windowHeight = window.innerHeight;
      addEventHandlers();
      checkPosition();
    }
    function addEventHandlers() {
      window.addEventListener('scroll', checkPosition);
      window.addEventListener('resize', init);
    }
    function checkPosition() {
      for (var i = 0; i < elems.length; i++) {
        var positionFromTop = elems[i].getBoundingClientRect().top;
        if (positionFromTop - windowHeight <= 0) {
          elems[i].className = elems[i].className.replace(
            'animatemeplz',
            'animated fadeIn'
          );
        }
      }
    }
    return {
      init: init
    };
  };
  animateHTML().init();

HTML

        <div class="menu">
      <div class="side-olay">
        <p class="side-num">01</p>
        <p class="side-nums">02</p>
        <p class="side-nums">03</p>
        <p class="side-nums">04</p>
      </div>
    </div>
<!-- START OF INITAL SCREEN -->
  <div class="head rellax" data-rellax-speed="-10">
    <img class="logo" src="img/logo.png">
    <div class="ld1"></div>
    <div class="ld2"></div>
    <div class="ld3"></div>
    <h3>SERVER <span style="font-weight: bold;">MOTTO</span></h3>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor<br> incididunt ut ero labore et dolore.</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor<br> incididunt ut ero labore et dolore.</p>
    <div class="line"></div>
    <a href="#" class="button1">Discord Server</a>
    <img class="side" src="img/side.png">
  </div>

  <div class="stats">
    <div class="chart animatemeplz">
      <div class="chart-olay">
        <ul>
          <li>100</li>
          <li>50</li>
          <li>25</li>
          <li>0</li>
        </ul>
      </div>
      <img src="img/Group%2012.png">
      <div class="chart-bar"></div>
      <div class="chart-bar"></div>
      <div class="chart-bar"></div>
      <div class="chart-bar"></div>
      <div class="chart-bar"></div>
      <div class="chart-bar"></div>
      <div class="chart-bar"></div>
      <div class="chart-bar"></div>
    </div>
    <h1 class="h1 animatemeplz">STATISTICS</h1>
    <p class="p1 animatemeplz">Lorem ipsum dolor sit amet,<br>consectetur adipsicing elit, sed do<br>eiusmod.</p>

    <h1 class="h2 animatemeplz">FILTER</h1> <a class="filer-btn animatemeplz">Today</a><a class="filer-btn animatemeplz">A Month Ago</a><a class="filer-btn animatemeplz">4 Months Ago</a>
    <p class="p2 animatemeplz">Filter our updated statistic log through clicking designated buttons to alter your filtered result.</p>
  </div>

  <div class="feat">
    <div class="featside">
      <div class="sidedot"></div>
      <div class="sidedot2"></div>
      <div class="sidedot3"></div>
    </div>
    <img class="featbg" src="img/featbg.png">
    <h1>Features</h1>
    <div class="line"></div>
    <H1><span id="typed">Down to Roleplay ping-able role (@DTRP)</span></H1>
    <!--<h1>Down to Roleplay ping-able role (@DTRP) </h1>-->
    <p style="margin-left: 20vw;">pingable only every 3 hours or something #DM-request ping spam</p>
  </div>

Expected Result: Animation plays when div is scrolled into view. Actual Result: Animation is played when the page is loaded even when div is not visible.

The issue would seem to depend on your CSS. Your JavaScript is replacing the .animatemeplz class with the .animate and .fadeIn classes for elements that enter the viewport, so CSS of the following form should ensure the animation works:

.animatemeplz {
    opacity: 0;
}
.animated {
    transition: opacity 1s;
}
.fadeIn {
    opacity: 1;
}

A cleaner way of doing it might be to give elements that require animations a single .animate class:

<h1 class="h1 animate">STATISTICS</h1>
<p class="p1 animate">Lorem ipsum dolor sit amet... etc</p>

with CSS for .animate and another class, .visible as follows:

.animate {
    transition: opacity 1s;
    opacity: 0;
}
.animate.visible {
    opacity: 1;
}

You could then toggle visibility using the JavaScript classList.add method.

...
if (positionFromTop - windowHeight <= 0) {
    elems[i].classList.add('visible');
} else {
    elems[i].classList.remove('visible');
}
...

This would fade out the elements when you scroll back up.


You are also calling checkPosition() on every scroll event. This will likely cause lag on some devices, especially if checkPosition() takes a while to compute. There are a number of ways to fix this, including debouncing where you would wait a specified length of time before calling checkPosition() again. Debouncing with a wait time of 100ms could be done by replacing the code where you add a scroll event listener with the following:

window.addEventListener( 'scroll', function() {
    if ( !checkPosition.debounce ) {
        checkPosition.debounce = setTimeout(function(){
            delete checkPosition.debounce;
            checkPosition();
        }, 100);
    }
} );

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM