jQuery Run CSS Animation only when content is visible to the user

Asked

Viewed 2,011 times

3

I’m using an animation library called Animate.css that can be seen clicking here.

But by creating an effect for a particular div the effect is activated even if the div is not being visible on the screen, that is, it is still necessary to scroll the page to make the div visible.

Follow the jQuery code I’m using:

$('#galeria-fotos-home').addClass('animated bounceInUp');

I want the effect to be activated only when the div is being visible, like on this website. Note that when scrolling the page the effects will appear.

3 answers

3


The problem is that you are (probably) adding the class when the DOM is ready (i.e., $(document).ready()...), and this does not mean that the element is visible. You can create a method that checks the "visibility" of an element during the scroll. See (taken out from here):

function isScrolledIntoView(elem){
    var docViewTop = $(window).scrollTop();
    var docViewBottom = docViewTop + $(window).height();

    var elemTop = $(elem).offset().top;
    var elemBottom = elemTop + $(elem).height();

    return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop));
}

and attach it to the scroll as follows

$(window).on('scroll', function(){
    if(isScrolledIntoView('.elemento')){
        console.log('elemento visivel');
    }
});

Note that this approach is costly, because this method will run every time that the event takes place scroll. For various elements, you may have performance problems.

Another point of attention is that you can add only the class .bounceIn, without worrying about the .animated. See a minimum example:

function isScrolledIntoView(elem){
    var docViewTop = $(window).scrollTop();
    var docViewBottom = docViewTop + $(window).height();

    var elemTop = $(elem).offset().top;
    var elemBottom = elemTop + $(elem).height();

    return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop));
}

$(window).on('scroll', function(){
  if(isScrolledIntoView('.animated')){
    $('.animated').addClass('bounceIn');
  }
  else{
    $('.animated').removeClass('bounceIn');
  }
});
.dummy{
  padding: 1em;
  border: 1px solid black;
  width: 50%;
  margin: 0 auto;
}

.animated{
  margin: 1em auto;
  text-align: center;
  border: 1px solid red;
  padding: 1em;
  width: 30%;
}

.animated.bounceIn{
  animation-duration: .75s;
}

.bounceIn {
  animation-name: bounceIn;
}

@keyframes bounceIn {
  from, 20%, 40%, 60%, 80%, to {
   animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
  }

  0% {
    opacity: 0;
    transform: scale3d(.3, .3, .3);
  }

  20% {
    transform: scale3d(1.1, 1.1, 1.1);
  }

  40% {
    transform: scale3d(.9, .9, .9);
  }

  60% {
    opacity: 1;
    transform: scale3d(1.03, 1.03, 1.03);
  }

  80% {
    transform: scale3d(.97, .97, .97);
  }

  to {
    opacity: 1;
    transform: scale3d(1, 1, 
  }
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="dummy">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptatibus similique excepturi, incidunt doloribus cum! Atque pariatur nostrum autem quaerat quis libero velit eligendi eaque culpa deserunt neque molestias dolorum nobis ab possimus aperiam quam vero corporis, qui unde debitis ut facilis, consequatur, laboriosam! Accusamus neque debitis nemo, harum mollitia magnam ratione aliquid optio, quia tempore earum! Culpa, rem. Perferendis animi doloribus maiores maxime quos repellendus iste, ex architecto a vel placeat cum nesciunt aliquam similique! Sunt est obcaecati illo rerum qui, inventore at. Doloremque nam animi eveniet consequuntur soluta architecto! Quae deserunt quisquam, libero ex labore mollitia quibusdam maiores commodi quaerat odio quam magnam minima praesentium corporis molestiae sint esse laudantium fuga impedit autem id. Dolore iure ex iste ad praesentium quidem omnis minus saepe facere nesciunt dignissimos soluta hic suscipit molestias rerum ut veritatis itaque eum voluptatibus non, modi corporis, laudantium earum perspiciatis. Fuga sint mollitia sit deserunt ab porro maiores, laudantium quae obcaecati optio corporis aut quidem nisi blanditiis eius veritatis animi, hic fugiat exercitationem! Tempore aut, corporis facilis iure voluptatem eaque libero amet odit culpa, esse. Alias, harum, maiores! Error laborum nostrum earum aliquam architecto repudiandae magni voluptatibus iusto deserunt. Blanditiis saepe tempore totam repellendus voluptates veniam molestias quia beatae adipisci optio eligendi, quae quos inventore tempora ad harum vel, aspernatur minima eos iste recusandae. Iusto ipsum tenetur, fugit autem nesciunt unde doloribus eligendi voluptatem quam odit in quae reprehenderit cum deserunt provident. Quia tempore enim, maxime minus quisquam repellat hic ea fugit nostrum iusto adipisci temporibus vero natus, illo. Tempora itaque est praesentium eaque vel et quasi iste recusandae non aspernatur fugit soluta laboriosam nulla voluptas quidem esse error, hic numquam odio repudiandae nihil ipsa, atque dolorum quisquam? Minus perferendis consectetur accusantium veniam amet, in, nulla iste voluptatem, mollitia ipsum facere dolores. Provident repudiandae non assumenda nostrum nam velit qui, ex impedit illo expedita animi adipisci enim eius natus voluptatibus porro consectetur quis. Dignissimos, excepturi dolorum aut libero laudantium obcaecati nobis perspiciatis iure. Nobis dicta amet consequatur necessitatibus deserunt exercitationem ipsum vero error nulla, aliquid inventore voluptatum possimus omnis voluptatibus suscipit velit nam, perferendis quos asperiores quisquam voluptates ducimus consequuntur sed. Eveniet deleniti, reprehenderit aliquid animi! Mollitia debitis quidem, amet consequatur nemo laudantium voluptatum recusandae, necessitatibus dicta nam alias, itaque eum rerum. Iure illum, natus dolor explicabo quae nam consequatur cupiditate, soluta</div>

<div class="animated">See me bounce!</div>

I believe your problem can be solved like this. But, taking advantage of the momentum, if you want to make animations based on scroll, that library is excellent.

  • Would this library you pointed out to me be a better option to integrate with what I want? Because my interest is to use about 4 different effects on each page.

  • I believe so... it already handles the animations and scroll at the same time, is very simple to use, and prevents you from getting lost if you add more things

  • http://codepen.io/michalsnik/pen/WxvNvE a pen with example of operation

  • I liked the example, would I add data-aos="meuefeito" through a jQuery function?

  • $('.el').attr('data-aos','meuefeito') ?

0

IE7 or higher: https://stackoverflow.com/a/7557433/5628

function onVisibilityChange(el, callback) {
    var old_visible;
    return function () {
        var visible = isElementInViewport(el);
        if (visible != old_visible) {
            old_visible = visible;
            if (typeof callback == 'function') {
                callback();
            }
        }
    }
}

var handler = onVisibilityChange($('#galeria-fotos-home'), function() {

    $('#galeria-fotos-home').addClass('animated bounceInUp');

    //uma vez que já tenha sido iniciada a animação, vamos desativá-la
    $(window).on('DOMContentLoaded load resize scroll', function(){}); 

});


//jQuery
$(window).on('DOMContentLoaded load resize scroll', handler); 

Note that monitoring the scroll of the page brings a considerable layer of complexity to your application, see if it is really worth incorporating this feature. If a loop animation counts, better.

0

What I was doing was a function that can be detected if the user is viewing or not...

To find out what the user is seeing

var init = $(window).scrollTop();     
var end  = $(window).height()+$(window).scrollTop();
// o utilizador ve tudo que estiver entre o $init e o $end

To know the position of the div

var init = $('.div').offset().top
var end  = $('.div').offset().top+$('.div').height()

I hope I explained myself well ;)

Functions you will need:

Browser other questions tagged

You are not signed in. Login or sign up in order to post.