首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >通过滚动触发CSS关键帧动画

问通过滚动触发CSS关键帧动画
EN

Stack Overflow用户
提问于 2016-01-23 03:45:38
回答 2查看 22.1K关注 0票数 4

假设我有一个带有动画的元素:

代码语言:javascript
复制
#element {
  animation: Fade 3s linear 1s forwards;
}

@keyframes Fade {
  /* do stuff */
}

如何才能仅在用户向下滚动时触发此动画?Vanilla JS,jQuery,ScrollMagic,GSAP/TweenMax,随便你怎么做。

添加动画属性本身会触发该效果吗?因此,用户滚动到某个点/元素,然后我应用如下内容:$('#element').css('animation', 'Fade 3s linear 1s forwards');

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-01-23 03:52:10

向元素添加一个类,当用户向下滚动时,该元素上有动画。

伪码

代码语言:javascript
复制
on window scroll {
  if (scroll pos > x) {
    element.addclass("animateMe");
  }
}

演示

http://jsbin.com/zuqexigepe/edit?html,output

如果您希望每次用户滚动经过某个点时都会发生动画,您可以简单地更改scroll事件来删除该类,如下所示:

代码语言:javascript
复制
$(window).scroll(function () {
  if($(window).scrollTop() > 0) {
    element.addClass("animateMe");
  }
  else {
    element.removeClass("animateMe");
  }
});
票数 3
EN

Stack Overflow用户

发布于 2019-10-04 14:57:10

发布的(和接受的)答案在技术上是正确的,但现在有更多性能友好的方法来实现这一点。如果要在多个元素上触发动画,查看这些多个元素可能会导致较差的性能。有关example this question,请参见。免责声明:这个问题也有我的答案,我只会在这篇文章中复制我自己的作品:

要以一种现代的、高性能的方式解决这个问题,最好使用Intersection Observer (IO)。

使用IO,您可以观察一个(或多个)元素,并在它们进入视图或它们彼此相交时做出反应。

要使用IO,首先必须为其设置选项,然后定义要监视的元素,最后定义IO触发后到底发生了什么。

示例(Taken from here),只做了最小的修改:即使动画还没有发生,作者也删除了IO。我将unobserve调用移到了check if元素可见的内部。

​

代码语言:javascript
复制
const SELECTOR = '.watched';
const ANIMATE_CLASS_NAME = 'animated';

const animate = element => (
  element.classList.add(ANIMATE_CLASS_NAME)
);

const isAnimated = element => (
  element.classList.contains(ANIMATE_CLASS_NAME)
);

const intersectionObserver = new IntersectionObserver((entries, observer) => {
  entries.forEach((entry) => {
    
    // when element's is in viewport,
    // animate it!
    if (entry.intersectionRatio > 0) {
      animate(entry.target);
      // remove observer after animation
      observer.unobserve(entry.target);
    }
  });
});

// get only these elements,
// which are not animated yet
const elements = [].filter.call(
  document.querySelectorAll(SELECTOR),
  element => !isAnimated(element, ANIMATE_CLASS_NAME)
);
//console.log(elements);

// start observing your elements
elements.forEach((element) => intersectionObserver.observe(element));
代码语言:javascript
复制
.h100 {
height: 100vh;
}

.watched {
 opacity: 0;
 transition: opacity .5s;
}

.watched.animated {
opacity: 1;
}
代码语言:javascript
复制
<div class="h100">
scroll down
</div>
<div class="watched">
I'm watched
</div>
<div class="h100">
Another element, keep scrolling
</div>
<div class="watched">
I'm also watched
</div>

​

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34954689

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档