CSS动画发生在滚动时,而不是页面加载时

时间:2019-06-29 05:16:50

标签: css css-animations

我的css动画有问题,它似乎动画是在页面加载后发生的,而不是在您滚动到该部分时出现的,如何使我的动画在您滚动到该部分而不是在页面加载后发生的?

这是我的样式元素:

.slick-slide:nth-child(odd) {
    -webkit-animation-name: fadeInLeft;
    -moz-animation-name: fadeInLeft;
    -o-animation-name: fadeInLeft;
    animation-name: fadeInLeft;
    -webkit-animation-duration: 1s;
    -moz-animation-duration: 1s;
    -o-animation-duration: 1s;
    animation-duration: 1s;
    -webkit-animation-delay: 1s;
    -moz-animation-delay: 1s;
    -o-animation-duration:1s;
    animation-delay: 1s;
}

这是我的关键帧

@-webkit-keyframes fadeInLeft {
    from {
        opacity:0;
        -webkit-transform: translatex(-10px);
        -moz-transform: translatex(-10px);
        -o-transform: translatex(-10px);
        transform: translatex(-10px);
    }
    to {
        opacity:1;
        -webkit-transform: translatex(0);
        -moz-transform: translatex(0);
        -o-transform: translatex(0);
        transform: translatex(0);
    }
}
@-moz-keyframes fadeInLeft {
    from {
        opacity:0;
        -webkit-transform: translatex(-10px);
        -moz-transform: translatex(-10px);
        -o-transform: translatex(-10px);
        transform: translatex(-10px);
    }
    to {
        opacity:1;
        -webkit-transform: translatex(0);
        -moz-transform: translatex(0);
        -o-transform: translatex(0);
        transform: translatex(0);
    }
}
@keyframes fadeInLeft {
    from {
        opacity:0;
        -webkit-transform: translatex(-100px);
        -moz-transform: translatex(-100px);
        -o-transform: translatex(-100px);
        transform: translatex(-100px);
    }
    to {
        opacity:1;
        -webkit-transform: translatex(0);
        -moz-transform: translatex(0);
        -o-transform: translatex(0);
        transform: translatex(0);
    }
}

2 个答案:

答案 0 :(得分:3)

无法通过纯CSS使事物了解滚动。当元素进入视图时,您将不得不使用JavaScript添加一个类。

一种方法是使用Intersection Observer API(如果您需要与旧版浏览器兼容,则可以在线使用polyfills。)

let observer = new IntersectionObserver(updates => {
    updates.forEach(update => {
        if (update.isIntersecting) {
            update.target.classList.add('visible');
        } else {
            update.target.classList.remove('visible');
        }
    });
}, { threshold: 0 });

[...document.querySelectorAll('.element')].forEach(element => observer.observe(element));

注意:如果您的动画使您的元素完全移到屏幕的一侧,则此方法将不起作用(或至少需要进行一些调整),因为该方法将永远不会与视口相交或触发反向动画。结束。

JSFiddle example

答案 1 :(得分:2)

这就是...

首先,我将动画与选择器本身分离,创建了一个仅包含动画信息的全新类,并添加了animation-fill-mode:forwards属性,以便动画在100%关键帧处结束。我添加了它,以便原始类具有opacity:0

CSS:

.slick-slide:nth-child(odd) {
  opacity:0;

}
.slick-slide.anim:nth-child(odd) {
  -webkit-animation-name: fadeInLeft;
  -moz-animation-name: fadeInLeft;
  -o-animation-name: fadeInLeft;
  animation-name: fadeInLeft;
  -webkit-animation-duration: 1s;
  -moz-animation-duration: 1s;
  -o-animation-duration: 1s;
  animation-duration: 1s;
  -webkit-animation-delay: 1s;
  -moz-animation-delay: 1s;
  -o-animation-duration: 1s;
  animation-delay: 1s;
  -webkit-animation-fill-mode:forwards;  // added
  animation-fill-mode:forwards;          // added
}

然后您需要此Javascript:

$(window).on('load scroll', function() {
    var scrollTop = $(window).scrollTop(),
        windowHeight = $(window).height(),
        threshold = 200;

  $('.slick-slide:nth-child(odd)').each(function() {
        var offTop=$(this).offset().top;
    if ((scrollTop+windowHeight) > offTop) { // you can add -threshold here as scrollTop+windowHeight-threshold in pixels
    $(this).addClass('anim');
    }
  });
});

JavaScript的作用是:一旦选择器类别之一出现在屏幕上-通过计算窗口scrollTop减去窗口height,然后将anim类应用到选择器。我还添加了一个可选的threshold变量,您可以使用该变量来更改动画触发的点-例如,屏幕上200px

我在示例中为slick-slide元素添加了一些样式,以便其中的一些最初不在屏幕上。

这是一个工作的小提琴。 https://jsfiddle.net/tun51xq6/1/