【发布时间】:2020-06-08 04:52:44
【问题描述】:
有没有办法让标题在到达下一个 div 时改变颜色?我试图让它在滚动到下一个 div“容器”时导航栏颜色发生变化
【问题讨论】:
标签: javascript css reactjs
有没有办法让标题在到达下一个 div 时改变颜色?我试图让它在滚动到下一个 div“容器”时导航栏颜色发生变化
【问题讨论】:
标签: javascript css reactjs
就像@neaumusic 已经回答的那样,添加滚动事件监听器会有所帮助。
这是我写的工作代码:codesandbox
我喜欢做的是将事件侦听器分离到一个自定义挂钩。
import { useEffect, useState, useRef, RefObject } from "react";
interface ITopBottom {
top: number;
bottom: number;
}
const useElementLocation = <T extends HTMLElement>(): [
RefObject<T>,
ITopBottom
] => {
// ref object to return
const ref = useRef<T>(null);
// you can customize this to include width, height, etc.
const [loc, setLoc] = useState<ITopBottom>({ top: 0, bottom: 0 });
useEffect(() => {
const listener = () => {
const rect = ref.current?.getBoundingClientRect()
if(rect){
setLoc({
top:rect.top,
bottom: rect.bottom,
})
}
};
// add the listener as the component mounts
window.addEventListener("scroll",listener)
// guarantee the listener is executed at least once
listener();
// clean up
return ()=>window.removeEventListener("scroll",listener)
}, []);
return [ref,loc]
};
export default useElementLocation;
这个钩子返回一个要放置在div中的ref对象,以及你需要的对应位置。
现在你知道了上下边界的位置,用逻辑语句判断header是否到达目标div,根据结果改变颜色。
import React, {useState, useEffect} from 'react'
import useElementLocation from "./useElementLocation"
export default () => {
const [headerRef, headerLoc] = useElementLocation<HTMLDivElement>();
const [divRef, divLoc] = useElementLocation<HTMLDivElement>();
const [headerColor, setHeaderColor] = useState("white"); // default color
useEffect(()=>{
const {bottom: headerBottom} = headerLoc;
const {top,bottom} = divLoc;
if(top<headerBottom && headerBottom<bottom){
// header has reached the div
setHeaderColor("black");
} else {
// header has left the div, either to the higher or lower
setHeaderColor("white");
}
},[divLoc, headerLoc]) //dependencies
return <div className="app">
<div className="header" style={{backgroundColor: headerColor}} ref={headerRef}></header>
<div className="div-to-watch" ref={divRef}></div>
</div>
}
【讨论】:
类似的东西
container.addEventListener('scroll', e => {
if (container.scrollTop > someChildElement.offsetTop) {
changeColor(navbar);
}
});
【讨论】: