import React , {useRef, useEffect} from 'react'
import './header.css'
const nav_links =[
{
path:'#home',
display:'Home'
},
{
path:'#about',
display:'About'
},
{
path:'#service',
display:'Service'
},
{
path:'#projects',
display:'Projects'
},
{
path:'#blog',
display:'Blog'
},
]
export default function Header({theme,toggleTheme}) {
const headerRef = useRef(null)
const headerFunc = () =>{
if(document.body.scrollTop > 80 || document.documentElement.scrollTop > 80){
headerRef.current.classList.add('header__shrink')
}else{
headerRef.current.classList.remove('header__shrink')
}
}
useEffect(()=>{
window.addEventListener('scroll', headerFunc)
return ()=> window.removeEventListener('scroll', headerFunc)
},[])
return (
<header className="header" ref={headerRef}>
<div className="container">
<div className="nav__wrapper">
<div className="logo">
<h2>Digency</h2>
</div>
{/* ========= navigation =========*/}
<div className="navigation">
<ul className="menu">
{
nav_links.map((item, index)=>(
<li className="menu__item" key={index}><a href={item.path} onClick={(e) =>{
e.preventDefault();
const targetAttr = e.target.getAttribute('href');
console.log('test',targetAttr)
const location = document.querySelector(targetAttr).offsetTop;
console.log('test2',location)
window.scrollTo({
left: 0,
top: location - 80,
});
}} className="menu__link">{item.display}</a></li>
))
}
</ul>
</div>
{/* ========= ligth mode =========*/}
<div className="light__mode">
<span onClick={toggleTheme}>
{
theme==='light-theme' ? (<span className='black'><i class="ri-moon-line"></i> Dark</span>) : (<span><i class="ri-sun-line"></i> Ligth</span>)
}
</span>
</div>
</div>
</div>
</header>
)
}
我的问题是
onlick
映射菜单,唯一可用的按钮是“博客”。其余按钮抛出此错误:
未捕获的类型错误:无法读取 null 的属性(读取“offsetTop”)
我尝试构建一个粘性标题,每个按钮上都有该功能,以将我发送到组件(通过外边框的距离)。我尝试记录
console.log(targetAttr)
,每个属性都在控制台中。问题是当我需要得到:
location = document.querySelector(targetAttr).offsetTop;
所以你的代码实际上很好,如下所示: https://codesandbox.io/s/vigorous-dewdney-5syxkr?file=/src/App.js
问题是您的代码中没有与您尝试获取的标记(路径属性)相对应的 HTML id 标记。
您可能会考虑的另一种方法是使用
.scrollIntoView
- 您可以在其中添加类似这样更干净的内容:
document.querySelector('#blog').scrollIntoView({behavior:'smooth'})
关于在 React 中使用它的好文章在这里: