基于滚动 React JS 的切换类

IT技术 javascript reactjs twitter-bootstrap events dom-events
2021-05-05 09:37:55

我正在使用 bootstrap 4 导航栏,并想在 ig 400px 向下滚动后更改背景颜色。我正在查看 react 文档并找到了一个 onScroll 但找不到关于它的太多信息。到目前为止我有...

我不知道我是否使用了正确的事件侦听器或如何设置高度等。

而且我并没有真正设置内联样式...

  import React, { Component } from 'react';

   class App extends Component {

   constructor(props) {
    super(props);

      this.state = {  scrollBackground: 'nav-bg' };
      this.handleScroll = this.handleScroll.bind(this);
   }


   handleScroll(){
      this.setState ({
         scrollBackground: !this.state.scrollBackground
       })
    }

 render() {
 const scrollBg = this.scrollBackground ? 'nav-bg scrolling' : 'nav-bg';

 return (
   <div>

       <Navbar inverse toggleable className={this.state.scrollBackground} 
                                  onScroll={this.handleScroll}>
        ...
      </Navbar>

    </div>
   );
  }
}

export default App;
4个回答

对于那些在 2020 年之后阅读这个问题的人,我已经回答了@glennreyes 并使用React Hooks重写了它

  const [scroll, setScroll] = useState(0)

  useEffect(() => {
    document.addEventListener("scroll", () => {
      const scrollCheck = window.scrollY < 100
      if (scrollCheck !== scroll) {
        setScroll(scrollCheck)
      }
    })
  })

请记住,useState有一个包含两个元素的数组,首先是状态对象,其次是更新它函数

沿着这条线,useEffect帮助我们替换componentDidmount,为了简洁起见,当前编写的函数没有做任何清理。

如果您发现清理很重要,您可以在useEffect 中返回一个函数

您可以在此处全面阅读

更新:

如果你们想把它module化,甚至做清理,你可以做这样的事情:

  1. 创建一个自定义钩子,如下所示;

    import { useState, useEffect } from "react"
    
    export const useScrollHandler = () => {
    // setting initial value to true
    const [scroll, setScroll] = useState(1)
    
    // running on mount
    useEffect(() => {
      const onScroll = () => {
        const scrollCheck = window.scrollY < 10
        if (scrollCheck !== scroll) {
          setScroll(scrollCheck)
        }
      }
    
    // setting the event handler from web API
    document.addEventListener("scroll", onScroll)
    
    // cleaning up from the web API
     return () => {
       document.removeEventListener("scroll", onScroll)
      }
    }, [scroll, setScroll])
    
    return scroll
    
    }
    
  2. 您认为合适的任何组件调用它

    const component = () => {
    
    // calling our custom hook
    const scroll = useScrollHandler()
    
    ....... rest of your code
    
    }
    

添加滚动侦听器的componentDidMount()一种方法是使用生命周期方法。下面的例子应该给你一个想法:

import React from 'react';
import { render } from 'react-dom';

class App extends React.Component {
  state = {
    isTop: true,
  };

  componentDidMount() {
    document.addEventListener('scroll', () => {
      const isTop = window.scrollY < 100;
      if (isTop !== this.state.isTop) {
          this.setState({ isTop })
      }
    });
  }
  render() {
    return (
      <div style={{ height: '200vh' }}>
        <h2 style={{ position: 'fixed', top: 0 }}>Scroll {this.state.isTop ? 'down' : 'up'}!</h2>
      </div>
    );
  }
} 

render(<App />, document.getElementById('root'));

当您的 scrollY 位置在 100 及以上时,这会将文本从“向下滚动”更改为“向上滚动”。

编辑:应该避免在每个滚动上更新状态的矫枉过正。仅在布尔值更改时更新它。

更好

import React from 'react';
import { render } from 'react-dom';

class App extends React.Component {
    constructor(props) {
    super(props);

    this.state = {
      isTop: true
    };
    this.onScroll = this.onScroll.bind(this);
  }

  componentDidMount() {
    document.addEventListener('scroll', () => {
      const isTop = window.scrollY < 100;
      if (isTop !== this.state.isTop) {
        this.onScroll(isTop);
      }
    });
  }

  onScroll(isTop) {
    this.setState({ isTop });
  }

  render() {
    return (
      <div style={{ height: '200vh' }}>
        <h2 style={{ position: 'fixed', top: 0 }}>Scroll {this.state.isTop ? 'down' : 'up'}!</h2>
      </div>
    );
  }
} 

render(<App />, document.getElementById('root'));
 const [scroll, setScroll] = useState(false);

 useEffect(() => {
   window.addEventListener("scroll", () => {
     setScroll(window.scrollY > specify_height_you_want_to_change_after_here);
   });
 }, []); 

然后您可以根据滚动更改您的课程或任何内容。

<nav className={scroll ? "bg-black" : "bg-white"}>...</nav>