简体   繁体   English

在 vanilla JS 中滚动动画

[英]Animate on scroll in vanilla JS

I know its easy to have triggers on scroll and to add class name to HTML elements through jquery , but I was wondering if it's possible (or even worth it) to try to do so in react or vanilla javascript .我知道在滚动上有触发器并通过jquery向 HTML 元素添加类名很容易,但我想知道是否有可能(甚至值得)尝试在 react 或 vanilla javascript这样做。 I am learning react and want to trigger animations when users have scrolled a certain distance of the web page.我正在学习反应并希望在用户滚动网页一定距离时触发动画。 I have not used jquery so far as many people advise that you should stick to vanilla javascript as much as possible as it is very powerful and you won't require importing the jquery libraries.到目前为止,我还没有使用过jquery ,因为很多人建议您应该尽可能地坚持使用 vanilla javascript ,因为它非常强大,而且您不需要导入jquery库。

I have implemented a scroll trigger in vanilla JS successfully with the following code bellow, although its very inefficient as it uses an event listener on the scroll (maybe Jquery does this anyway though?).我已经使用下面的代码在 vanilla JS 中成功实现了滚动触发器,尽管它非常低效,因为它在滚动上使用事件侦听器(尽管Jquery可能Jquery ?)。 Is jquery simply the best way to do what I want? jquery 只是做我想做的最好的方法吗? Thanks in advance guys, here is the spaghetti code:在此先感谢大家,这是意大利面条代码:

function getDocHeight(D) {
  return Math.max(
      D.body.scrollHeight, D.documentElement.scrollHeight,
      D.body.offsetHeight, D.documentElement.offsetHeight,
      D.body.clientHeight, D.documentElement.clientHeight
  )
}

  function amountscrolled(){
var winheight= window.innerHeight || (document.documentElement || document.body).clientHeight
var docheight = getDocHeight(document)
var scrollTop = window.pageYOffset || (document.documentElement || document.body.parentNode || document.body).scrollTop
var trackLength = docheight - winheight
var pctScrolled = Math.floor(scrollTop/trackLength * 100) // gets percentage scrolled (ie: 80 or NaN if tracklength == 0)

if (pctScrolled > 50) {
  document.getElementById('anim').className+=" animate";
}
}

window.addEventListener("scroll", function(){
amountscrolled()
}, false)

Using jQuery with ReactJS is usually frowned upon mainly because js doesn't expect anything else touching the DOM. 通常不赞成将jQuery与ReactJS一起使用,主要是因为js不需要其他任何东西来接触DOM。 Since Reactjs uses a virtual DOM, and jQuery touches the DOM itself, you'll find that some weird things start to happen. 由于Reactjs使用虚拟DOM,而jQuery接触DOM本身,因此您会发现一些奇怪的事情开始发生。

This is an old question, but the only existing answer is completely unrelated, and there is a great way to do this now – the IntersectionObserver API.这是一个古老的问题,但唯一存在的答案是完全不相关的,现在有一种很好的方法可以做到这一点IntersectionObserver API。

 const callback = (entries) => entries.forEach(entry => entry.isIntersecting && entry.target.classList.add("show") ); const observer = new IntersectionObserver(callback); const animate = document.querySelectorAll(".animate"); animate.forEach(div => observer.observe(div));
 body { margin: 0; padding: 0; display: flex; flex-direction: column; } body > * + * { margin-top: 1em } #content { height: 100vh; background: red; } .animate { height: 20vh; background: blue; opacity: 0; transition: opacity 1s; } .animate.show {opacity: 1}
 <div id="content">content</div> <div class="animate">animate me 1</div> <div class="animate">animate me 2</div> <div class="animate">animate me 3</div>

The best part is that for your React needs, there is even a library you can use!最好的部分是,对于您的 React 需求,您甚至可以使用一个库! react-intersection-observer反应交叉观察者

$ npm install react-intersection-observer --save
$ # or
$ yarn add react-intersection-observer

(from the README) (来自自述文件)

import React from 'react';
import { useInView } from 'react-intersection-observer';

const Component = () => {
  const { ref, inView, entry } = useInView({
    /* Optional options */
    threshold: 0,
  });

  return (
    <div ref={ref}>
      <h2>{`Header inside viewport ${inView}.`}</h2>
    </div>
  );
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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