【问题标题】:What can I change to make this code work with all section elements我可以更改什么以使此代码适用于所有部分元素
【发布时间】:2020-04-13 08:27:52
【问题描述】:

所以我得到了这段代码,当该部分位于视口中时,它添加了一个类名,到目前为止,它只适用于第一个元素,因为我使用的是 querySelector,但如果我有机会 querySelectorAll 它不起作用。

我正在尝试在用户滚动页面时为每个部分添加动画,无论是向上还是向下。

import React from 'react';

const EffectComponent = () => {
  const vpPlitz = (element) => {
    const scroll = window.scrollY || window.pageYOffset;
    const boundsTop = element.getBoundingClientRect().top + scroll;

    const viewport = {
      top: scroll,
      bottom: scroll + window.innerHeight,
    };

    const bounds = {
      top: boundsTop,
      bottom: boundsTop + element.clientHeight,
    };

    return (
      (bounds.bottom >= viewport.top && bounds.bottom <= viewport.bottom) ||
      (bounds.top <= viewport.bottom && bounds.top >= viewport.top)
    );
  };

  // Usage.
  document.addEventListener('DOMContentLoaded', () => {
    const answer = document.querySelector('section');

    const handler = () => {
      return vpPlitz(answer)
        ? answer.classList.add('section-animated')
        : answer.classList.remove('section-animated');
    };

    handler();
    window.addEventListener('scroll', handler);
  });

  return null;
};

export default EffectComponent;

更新:

感谢 Thet 的帮助,我能够更改 React。如果有人可能使用它,我会发布它。

import { useEffect } from 'react';

const EffectComponent = () => {
  useEffect(() => {
    const answers = document.querySelectorAll('section');

    const handler = (answer) => {
      return vpPlitz(answer)
        ? answer.classList.add('section-animated')
        : answer.classList.remove('section-animated');
    };

    window.addEventListener('scroll', () => {
      answers.forEach((answer) => handler(answer));
    });
  }, []);

  const vpPlitz = (element) => {
    const scroll = window.scrollY || window.pageYOffset;
    const boundsTop = element.getBoundingClientRect().top + scroll;

    const viewport = {
      top: scroll,
      bottom: scroll + window.innerHeight,
    };

    const bounds = {
      top: boundsTop,
      bottom: boundsTop + element.clientHeight,
    };

    return (
      (bounds.bottom >= viewport.top && bounds.bottom <= viewport.bottom) ||
      (bounds.top <= viewport.bottom && bounds.top >= viewport.top)
    );
  };

  return null;
};

export default EffectComponent;```

【问题讨论】:

    标签: javascript reactjs react-router-dom mern


    【解决方案1】:

    querySelectorAll() 返回一个元素数组,因此,如果你想为每个元素添加或删除类,你需要遍历数组。例如,

        const answers - document.querySelectorAll('section');
        const handler = (answer) => {
           return vpPlitz(answer)
                ? answer.classList.add('section-animated')
                : answer.classList.remove('section-animated');
        };
        window.addEventListener('scroll',() => {
           answers.forEach(answer => handler(answer));
       })
    

    您还应该在卸载组件时移除事件侦听器。您可以使用事件监听器:beforeunload。在其中运行与为 DOMContentloaded 运行的完全相同的函数,但将 window.addEventListener('scroll', handler(answer) 替换为 window.removeEventListener('scroll', handler(answer)

    【讨论】:

    • 嗨,您的代码很好,但是正在将类名添加到所有部分元素中,我想要的是只有当 a 部分在视口中时才会添加类名。
    • 我刚刚向您展示了您需要更换的部件。在不需要更改之前,我不一定要重写您拥有的相同代码。所以,我写的部分是在 DOMContentLoaded 回调函数里面。我以为你会明白的。
    • 这里是关于类和生命周期钩子的反应文档,如果你想了解它。 reactjs.org/docs/state-and-lifecycle.html
    • 太好了。赶上!。如果您正在使用 react,请尽量避免直接使用 DOM。 React 几乎提供了文档属性提供的几乎所有东西。
    • 组件卸载时还需要清理事件监听器。幸运的是,你可以在 useEffect 钩子中做到这一点。这是文档-reactjs.org/docs/hooks-effect.html。我希望你能更新你的答案更好。我也可以帮忙,我要。但我希望你先自己尝试一下。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-20
    • 2019-09-15
    • 1970-01-01
    • 2013-10-30
    • 2020-08-21
    相关资源
    最近更新 更多