javascript ReactJS 在滚动和到达特定位置时更改元素的颜色
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/48458832/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
ReactJS change color of element on scroll and when certain position is reached
提问by ST80
Is it possible to change the class of my header so that it will change its color when the background changes? I have a header and some sections. The header is fixed and when it foreaxmple reaches a section with a different backgroundcolor, I want to change the headers color for better readability, but I don't know how to do that. I've searched the web for it but I couldn't eally find something.
是否可以更改标题的类,以便在背景更改时更改其颜色?我有一个标题和一些部分。标题是固定的,当它到达具有不同背景颜色的部分时,我想更改标题颜色以提高可读性,但我不知道该怎么做。我已经在网上搜索过它,但我找不到任何东西。
this is what I got so far: (see this JSFIDDLE)
这就是我到目前为止所得到的:(见这个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>
)
}
}
the CSS:
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;
}
So, are there any hints?
那么,有什么提示吗?
回答by Liren Yeo
Try this:
试试这个:
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>
)
}
}
Basically we just use window.scrollYto know where has the user scrolled to.
基本上我们只是window.scrollY用来知道用户滚动到哪里。
回答by trixn
You could make your sections own components that keep a reference to their DOM element. Your Section component could then listen to a scroll event and invoke a callback that it has been given by the parent container when the top of your components DOM element reaches your fixed header.
您可以让您的部分拥有保留对其 DOM 元素的引用的组件。然后,当您的组件 DOM 元素的顶部到达您的固定标题时,您的 Section 组件可以侦听滚动事件并调用父容器提供的回调。
Your Section component could look something like this.
您的 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>
);
}
}
Then you could render your sections like this:
然后你可以像这样渲染你的部分:
<Section id="section-1" changeHeaderColor={this.changeColor}> content here </Section>
回答by Yohan
You could do this with React Hooks. This is what I did below.
你可以用 React Hooks 做到这一点。这就是我在下面所做的。
Here is a Code SandBox to help. (https://codesandbox.io/s/header-change-color-onscrolly-2z3vt)
这里有一个代码沙盒可以提供帮助。(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 file.
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;
}
回答by Devyn
The answer using hooks in React 16
在 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>
)
}
}
回答by learner
This is how I would go:
这就是我要去的方式:
I will bind a function on scroll in componentDidMount:
我将在 componentDidMount 中绑定一个滚动函数:
window.addEventListener("scroll", this.boundFun, false);
I will defined the function and add reference in constructor:
我将定义函数并在构造函数中添加引用:
constructor:
构造函数:
this.boundFun = this.scrollListingFun.bind(this);
I will add logic in:
我将添加逻辑:
scrollListingFun() {
// add logic for checks here.
}

