I'm using a single page template with GatsbyJS on which the menu scrolls to the different sections of the same page (#home, #about, #portfolio, etc). Is there a way to set an active classname on the links, highlighting the link the user is on?
答案 0 :(得分:1)
您可以设置activeStyle
或activeClassName
道具,以便在与当前网址匹配时为渲染元素添加样式属性,而Gatsby也支持React Router的道具exact
,{{1 },strict
和isActive
。如果设置了任何这些道具,则将使用React Router的location
组件而不是默认链接。
示例:
NavLink
答案 1 :(得分:1)
我努力工作,因为我无法找到另一种解决方案:
import React, { Component } from 'react';
import './Menu.css';
class Menu extends Component {
constructor(props) {
super(props)
this.state = {
home: true,
about: false,
portfolio: false
}
this.handleActive = this.handleActive.bind(this)
}
handleActive(button) {
switch (button) {
case 'home':
this.setState({
home: true,
about: false,
portfolio: false
});
break;
case 'about':
this.setState({
home: false,
about: true,
portfolio: false
});
break;
case 'portfolio':
this.setState({
home: false,
about: false,
portfolio: true
});
break;
default: break;
}
}
render() {
return (
<div id="nav-wrap">
<nav>
<input type="checkbox" id="checkbox1" />
<label htmlFor="checkbox1">
<ul className="menu first">
<li><a
className={this.state.home ? 'active' : null}
onClick={() => this.handleActive('home')}
href="#home">HOME</a></li>
<li><a
className={this.state.about ? 'active' : null}
onClick={() => this.handleActive('about')}
href="#about">ABOUT МЕ
</a></li>
<li><a
className={this.state.portfolio ? 'active' : null}
onClick={() => this.handleActive('portfolio')}
href="#portfolio">PORTFOLIO</a></li>
</ul>
<span className="toggle">☰</span>
</label>
</nav>
</div>
)
}
}
export default Menu;
答案 2 :(得分:0)
几周前,我做了一个网站,使用此功能。我创建了一个函数来知道哪个部分是活动的,并将其置于状态中。每当用户移动滚动条时,都会调用此功能。
在渲染中,我根据状态元素更改元素的de className。在我要跟踪的每个部分/元素中,我都添加了一个ID。
使用功能:
/**
* Helper function to get an element's exact position
* @param {element} element
* @return {x,y}
*/
export function getPosition(el) {
var xPos = 0;
var yPos = 0;
while (el) {
if (el.tagName == "BODY") {
// deal with browser quirks with body/window/document and page scroll
var xScroll = el.scrollLeft || document.documentElement.scrollLeft;
var yScroll = el.scrollTop || document.documentElement.scrollTop;
xPos += (el.offsetLeft - xScroll + el.clientLeft);
yPos += (el.offsetTop - yScroll + el.clientTop);
} else {
// for all other non-BODY elements
xPos += (el.offsetLeft - el.scrollLeft + el.clientLeft);
yPos += (el.offsetTop - el.scrollTop + el.clientTop);
}
el = el.offsetParent;
}
return {
x: xPos,
y: yPos
};
}
在React组件上:
componentDidMount() {
window.addEventListener('scroll', this.handleScroll);
this.handleScroll();
}
componentWillUnmount() {
window.removeEventListener('scroll', this.handleScroll);
}
handleScroll() {
const {inAnimation} = this.state;
let activeElement = false;
this.props.data.items.forEach((value,i) => {
let element = document.getElementById(value.url.substring(1));
if(getPosition(element).y <= 0){
activeElement = value.url;
}
});
this.setState({
activeElement
});
}
}
render(){
...
items.map((item, i) => {
return <li key={i}>
<a className={'menu-item' + (activeElement == item.url ? ' active': '')}>{item.title}</a>
</li>;
});
...
}
答案 3 :(得分:0)
链接提供了两个用于将样式添加到活动链接的选项:
activeStyle
—一种样式对象,仅在当前项目处于活动状态时才会应用
activeClassName
—仅在当前项目处于活动状态时才会添加到链接中的类名
关注官方文档:https://www.gatsbyjs.org/docs/gatsby-link/#add-custom-styles-for-the-currently-active-link
import React from "react"
import { Link } from "gatsby"
const SiteNavigation = () => (
<nav>
<Link
to="/"
{/* This assumes the `active` class is defined in your CSS */}
activeClassName="active"
>
Home
</Link>
<Link
to="/about/"
activeStyle={{ color: "red" }}
>
About
</Link>
</nav>
)
答案 4 :(得分:0)
如上面评论中的brooksrelyt所述,您可以轻松地使用react-scrollspry
将唯一的类名添加到已单击的哈希链接。这是我的用法:
import { Text } from 'rebass/styled-components'
import Scrollspy from 'react-scrollspy'
<Scrollspy
items={['home', 'features', 'faq']}
currentClassName="isCurrent"
>
<Link to="#home">Home</Link>
<Link to="#features">Features</Link>
<Link to="#faq">FAQ</Link>
</Scrollspy>
<Text id="home">Home</Text>
<Text id="features" mt={'400vh'}>Features</Text>
<Text id="faq" mt={'150vh'}>FAQ</Text>
简而言之,您使用Scrollspy
组件包装链接,并(至少)包括两个强制性道具:items
和currentClassName
。
items
是哈希名称的数组(不包含哈希字符)currentClassName
是您要添加到所选链接的类的名称。注意:我包括了rebass
文本组件,因为当我使用简单的div时,它对我来说无法正常工作。您应read the documentation了解如何在特定情况下使用它-因为在不同情况下可能还需要其他道具。