繁体   English   中英

ReactJS 改变滚动元素的颜色,当达到某个 position

[英]ReactJS change color of element on scroll and when certain position is reached

是否可以更改我的 header 的 class 以便在背景更改时更改其颜色? 我有一个 header 和一些部分。 header 是固定的,当它到达具有不同背景颜色的部分时,我想更改标题颜色以提高可读性,但我不知道该怎么做。 我已经在 web 中搜索了它,但我找不到任何东西。

这是我到目前为止得到的:(见这个JSFIDDLE

class Div extends React.Component{
   constructor() {
     super()

     this.state = {
       headerClass: 'white'
     }
}
changeColor() {
  // something like
     this.setState({ headerClass: 'black'})
}
render(){
  return(
    <div>
      <div id="header">
        <h1 className={`${this.state.headerClass}`}>
          This is the header
        </h1>
     </div>      
     <div id="section_1" className="section">
        This is section 1
     </div>

     <div id="section_2" className="section">
        This is section 2
     </div>

     <div id="section_3" className="section">
        This is section 3
     </div>

     <div id="section_4" className="section">
        This is section 4
     </div>

     <div id="section_5" className="section">
        This is section 5
     </div>

   </div>
   )
 }
}

CSS:

#main {
 height: 2000px;
 position: relative;
}

#section_1 {
  background: grey;
}

.section {
  height: 400px;
  background: white;
  padding: 30px 0;
}

#header {
  height: 50px;
  background: transparent;
  position: fixed;
  width: 100%;
  left: 0;
  top: 0;
  right: 0;
  z-index: 1
}

h1 {
 color: white;
}

那么,有什么提示吗?

试试这个:

import React from 'react'

export default class Div extends React.Component{
  state = {
    color: 'white'
  }

  listenScrollEvent = e => {
    if (window.scrollY > 400) {
      this.setState({color: 'black'})
    } else {
      this.setState({color: 'white'})
    }
  }

  componentDidMount() {
    window.addEventListener('scroll', this.listenScrollEvent)
  }

  render() {
    return(
      <div>
        <div id="header">
          <h1 style={{color: this.state.color}}>
            This is the header
          </h1>
       </div>
       <div id="section_1" className="section">
          This is section 1
       </div>

       <div id="section_2" className="section">
          This is section 2
       </div>

       <div id="section_3" className="section">
          This is section 3
       </div>

       <div id="section_4" className="section">
          This is section 4
       </div>

       <div id="section_5" className="section">
          This is section 5
       </div>

     </div>
     )
   }
}

基本上我们只是使用window.scrollY来知道用户滚动到哪里。

你可以用 React Hooks 做到这一点。 这就是我在下面所做的。

这是一个用于查看所有文件的代码沙盒。 它有 body.js 和 styles.css 来帮助显示滚动时的变化。 下面是 Header 组件及其 css 文件。 希望这有帮助! https://codesandbox.io/s/header-change-color-onscrolly-2z3vt

// Header Component

import React, { useState, useEffect } from 'react'

import "./Header.css"

function Header2() {
const [header, setHeader] = useState("header")

const listenScrollEvent = (event) => {
  if (window.scrollY < 73) {
    return setHeader("header")
  } else if (window.scrollY > 70) {
    return setHeader("header2")
  } 
}

useEffect(() => {
  window.addEventListener('scroll', listenScrollEvent);

  return () =>
    window.removeEventListener('scroll', listenScrollEvent);
}, []);

  return (
    <header className={header}>
      <div className="logo">Logo</div>
      <ul className="links">
        <li className="link-item">home</li>
        <li className="link-item">about</li>
        <li className="link-item">join</li>
      </ul>
    </header>
  );
}

export default Header2;

css 文件。

// Styles header.css

.header {
  position: absolute;
  top: 0;
  left: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  height: 120px;
  background-color: #fff;
  color: #333;
  transform: translateY(0);
  transition: transform 0.6s ease;
}

.header2 {
  position: fixed;
  top: 0;
  left: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  height: 86px;
  background-color: gray;
  color: rosybrown;
  transform: translateY(10);
  transition: transform 6s ease;
  animation: myanimation 3s;
}
@keyframes myanimation {
  0% {
    background-color: transparent;
    color: transparent;
  }
  35% {
    background-color: gray;
    color: rosybrown;
  }
  100% {
    background-color: gray;
    color: rosybrown;
  }
}

.logo {
  margin: 0 24px;
  font-size: 28px;
  color: #f59596;
}

.links {
  padding: 0;
  margin: 0 24px;
}

.link-item {
  display: inline-block;
  margin: 0 12px;
  cursor: pointer;
}

您可以让您的部分拥有保留对其 DOM 元素的引用的组件。 然后,当组件 DOM 元素的顶部到达固定标题时,您的 Section 组件可以侦听滚动事件并调用父容器提供的回调。

您的 Section 组件可能看起来像这样。

class Section extends React.Component {

    ref = node => {
        this.ref = node;
        window.addEventListener('scroll', this.onScroll);
    }

    componentWillUnmount() {
        window.removeEventListener('scroll', this.onScroll);
    }

    onScroll = event => {
        const {changeHeaderColor} = this.props;
        // calculate if the top value is inside your header by using the ref
        if (...) {
            changeHeaderColor();
        }
    }

    render() {
        const {id, children} = this.props;

        return (
            <div id={id} className="section" ref={this.ref}>{children}</div>
        );
    }
}

然后你可以像这样渲染你的部分:

<Section id="section-1" changeHeaderColor={this.changeColor}> content here </Section>

在 React 16 中使用钩子的答案

import React from 'react'

export default Div => (){
  const [headerColor, setHeaderColor] = useState("white")


const listenScrollEvent = () => {
    window.scrollY > 10
      ? setHeaderColor("black")
      : setHeaderColor("white")
  }
// Similar to componentDidMount and componentDidUpdate:
useEffect(() => {
  window.addEventListener("scroll", listenScrollEvent)
})

render() {

return(
  <div>
    <div id="header">
      <h1 style={{color: headerColor}}>
        This is the header
      </h1>
   </div>
   <div id="section_1" className="section">
      This is section 1
   </div>

   <div id="section_2" className="section">
      This is section 2
   </div>

   <div id="section_3" className="section">
      This is section 3
   </div>

   <div id="section_4" className="section">
      This is section 4
   </div>

   <div id="section_5" className="section">
      This is section 5
   </div>

 </div>
 )
 }
}

这就是我要去的方式:

我将在 componentDidMount 中绑定一个滚动函数:

window.addEventListener("scroll", this.boundFun, false);

我将定义函数并在构造函数中添加引用:

构造函数:

    this.boundFun = this.scrollListingFun.bind(this);

我将添加逻辑:

scrollListingFun() {
  //  add logic for checks here.
}

试试这个 `import React, { useState } from 'react'; 导入'./Navbar.css';

const NavBar = () => {

const [navbar, setNavbar] = useState(false);
const [TextHome,setTextHome]=useState(false);
const [TextAbout,setTextAbout]=useState(false);
const [TextService,setTextService]=useState(false);
const [TextPortfolio,setTextPortfolio]=useState(false);
const [TextContact,setTextContact]=useState(false);


const changeBackground = () => {
    if (window.scrollY >= 200) {
        console.log(window.scrollY);
        setNavbar(true);
        setTextHome(true);
         if (window.scrollY >= 600 && window.scrollY <= 920 ) {
            setTextAbout(true);
            setTextService(false);
            setTextPortfolio(false);
            setTextContact(false);




        }
        else if (window.scrollY >=921 && window.scrollY <= 1500 ) {
            setTextService(true);
            setTextAbout(false);
            setTextPortfolio(false);
            setTextContact(false);


        }
        else if (window.scrollY >= 1501 && window.scrollY <= 2250) {
            setTextPortfolio(true);
            setTextService(false);
            setTextAbout(false);
            setTextContact(false);

        }
        else if (window.scrollY >= 2251) {
            setTextContact(true);
            setTextPortfolio(false);

        }
        else {
            setTextAbout(false);
            setTextService(false);
            setTextPortfolio(false);
            setTextContact(false);



        }

    }

    else {
        setNavbar(false);
        setTextHome(false);
        // setTextAbout(false);
        // setTextService(false);
        // setTextPortfolio(false);
        // setTextContact(false);



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




return (
    <nav className={navbar ? "navbar active navbar-expand-lg navbar-light fixed-top py-3" : "navbar navbar-expand-lg navbar-light fixed-top py-3"} id="mainNav">
        <div className="container">
            <Link smooth className="navbar-brand nav-link " to="/#app">Start Bootstrap</Link>
            <button className="navbar-toggler navbar-toggler-right" type="button" data-toggle="collapse" data-target="#navbarResponsive" aria-controls="navbarResponsive" aria-expanded="false" aria-label="Toggle navigation"><span className="navbar-toggler-icon"></span></button>
            <div className="collapse navbar-collapse" id="navbarResponsive">

                    <ul className="navbar-nav ml-auto my-2 my-lg-0">
                        <li className="nav-item active"><Link smooth className="nav-link" style={{color:TextHome?"orange":"#000"}} to="/#app">Home</Link></li>
                        <li className="nav-item"><Link smooth className="nav-link  " style={{color:TextAbout?"orange":"#000"}}  to="/#about">About</Link></li>
                        <li className="nav-item"><Link smooth className="nav-link  " style={{color:TextService?"orange":"#000"}}  to="/#services">Services</Link></li>
                        <li className="nav-item"><Link smooth className="nav-link  " style={{color:TextPortfolio?"orange":"#000"}} to="/#portfolio">Portfolio</Link></li>
                        <li className="nav-item"><Link smooth className="nav-link  " style={{color:TextContact?"orange":"#000"}}  to="/#contact">Contact</Link></li>
                </ul>
            </div>
        </div>
    </nav>
);

} 导出默认导航栏;`

这是更改 header 的背景颜色的另一种简洁方法。

useEffect(() => {
    let header = document.getElementById("header");
    window.addEventListener("scroll", () => {
      if (window.scrollY > 100) {
        header.style.background = "red"
      } else {
        header.style.background = "transparent"
      }
    })
  })

暂无
暂无

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

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