admin管理员组文章数量:1405508
I am Using GatsbyJs and am trying to acplish a active class toggle. I have a simple Component posed of a anchor tag with a span inside. I want to change some css by toggling a active class on the anchor when it is clicked. Here is my code so far, I am also using styled-ponents. I tried some vanilla js in the broken code section below, that obviously didn't work hence broken code.
Thanks in advance
styles
const Menu = styled.a`
position: absolute;
cursor: pointer; padding: 10px 35px 16px 0px;
span, span:before, span:after{
cursor: pointer;
border-radius: 1px;
height: 5px;
width: 35px;
background: #000000;
position: absolute;
display: block;
content: '';
transition: all 200ms ease-in-out;
}
span:before{
top: -10px;
}
span:after{
bottom: -10px;
}
.active span{
background-color: transparent;
}
.active span:before, .active span:after{
top:0;
}
.active span:before{
transform: rotate(45deg);
}
.active span:after{
transform: rotate(-45deg);
}
`
ponent
const TemplateWrapper = ({ children }) => (
<div>
<Wrapper>
<Menu id="nav-toggle" className="menu"><span></span></Menu>
{children()}
</Wrapper>
</div>
)
TemplateWrapper.propTypes = {
children: PropTypes.func,
}
export default TemplateWrapper
broken code
document.querySelector( "#nav-toggle" )
.addEventListener( "click", function() {
this.classList.toggle( "active" );
});
This is the html that is rendered
<a class="menu sc-bwzfXH SqHLW" id="nav-toggle"><span></span></a>
I am Using GatsbyJs and am trying to acplish a active class toggle. I have a simple Component posed of a anchor tag with a span inside. I want to change some css by toggling a active class on the anchor when it is clicked. Here is my code so far, I am also using styled-ponents. I tried some vanilla js in the broken code section below, that obviously didn't work hence broken code.
Thanks in advance
styles
const Menu = styled.a`
position: absolute;
cursor: pointer; padding: 10px 35px 16px 0px;
span, span:before, span:after{
cursor: pointer;
border-radius: 1px;
height: 5px;
width: 35px;
background: #000000;
position: absolute;
display: block;
content: '';
transition: all 200ms ease-in-out;
}
span:before{
top: -10px;
}
span:after{
bottom: -10px;
}
.active span{
background-color: transparent;
}
.active span:before, .active span:after{
top:0;
}
.active span:before{
transform: rotate(45deg);
}
.active span:after{
transform: rotate(-45deg);
}
`
ponent
const TemplateWrapper = ({ children }) => (
<div>
<Wrapper>
<Menu id="nav-toggle" className="menu"><span></span></Menu>
{children()}
</Wrapper>
</div>
)
TemplateWrapper.propTypes = {
children: PropTypes.func,
}
export default TemplateWrapper
broken code
document.querySelector( "#nav-toggle" )
.addEventListener( "click", function() {
this.classList.toggle( "active" );
});
This is the html that is rendered
<a class="menu sc-bwzfXH SqHLW" id="nav-toggle"><span></span></a>
Share
Improve this question
edited Apr 5, 2018 at 1:14
Anders Kitson
asked Apr 4, 2018 at 22:01
Anders KitsonAnders Kitson
1,5456 gold badges44 silver badges115 bronze badges
5
-
1
Can you post the react code where
#nav-toggle
gets rendered ? – Tareq Commented Apr 4, 2018 at 22:04 - Ok I added what is rendered above. Also I fixed something in the menu ponent it was missing the nav-toggle id. However the broken code section doesn't even allow the app to run. If I delete it the app runs and everythingrenders fine. – Anders Kitson Commented Apr 4, 2018 at 22:10
- I see the problem, you need to add "&" before ".active span" in your styled ponent. like &.active span ... – m0rjjj Commented Apr 4, 2018 at 22:12
- And what's the error that you get? – m0rjjj Commented Apr 4, 2018 at 22:13
- @m0rjjj the site pletely crashes when I include the broken just, so the css part is working however I haven't tested add the active class manually so you might be partly right. – Anders Kitson Commented Apr 4, 2018 at 22:21
2 Answers
Reset to default 2Okay, you can take a look here REACT - toggle class onclick . There are several answers that show the way how you can achieve that, but things get messier when you want to use more than one class.
I like this package to handle the cases where you deal with styling with multiple classes based on the props or state: https://github./JedWatson/classnames.
I simplified the styles for the sake of clarity of this answer and assumed that the menu
is a global class, you want to apply as well.
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import styled from 'styled-ponents';
const Wrapper = styled.div``;
const Menu = styled.a`
span {
color: green;
}
&.active span {
color: blue;
}
`;
class TemplateWrapper extends Component {
state = {
isActive: false
};
handleClick = () => {
this.setState(state => ({ isActive: !state.isActive }));
};
render() {
const menuClass = classNames({
menu: true,
active: this.state.isActive
});
return (
<Wrapper>
<Menu id="nav-toggle" className={menuClass} onClick={this.handleClick}>
<span>Test</span>
</Menu>
{this.props.children}
</Wrapper>
);
}
}
TemplateWrapper.propTypes = {
children: PropTypes.node
};
TemplateWrapper.defaultProps = {
children: null
};
export default TemplateWrapper;
Notice the ampersand (&) before .active
. As stated in the docs, styled ponents
supports all of CSS plus nesting.
Ampersands (&) get replaced by our generated, unique classname for that styled ponent, making it easy to have plex logic.
However, you can achieve the same effect without classnames
by fully utilizing styled ponents functionality. Take a look at this section of the documentation.
A few changes needed:
const Menu = styled.a`
span {
color: ${props => (props.active ? 'blue' : 'green')};
}
`;
The render method would look like that:
render() {
return (
<Wrapper>
<Menu id="nav-toggle" className="menu" active={this.state.isActive} onClick={this.handleClick}>
<span>Test</span>
</Menu>
{this.props.children}
</Wrapper>
);
}
You can use ponent state
to mange this.
Code will look like:
Updated: Moved logic to Menu
ponent as it makes more sense to place it there. Below working example
class Menu extends React.Component {
constructor(props) {
super(props);
this.menuClick = this.menuClick.bind(this);
this.state = {
menuClass: '',
}
}
menuClick(e) {
const menuClass = this.state.menuClass === '' ? 'active' : '';
this.setState({ menuClass });
}
render() {
const {children, id} = this.props;
const menuClassName = `menu sc-bwzfXH SqHLW nav-toggle ${this.state.menuClass}`;
return (<a className={menuClassName} id={id} onClick={this.menuClick}>{children}</a>);
}
}
ReactDOM.render(<Menu><span>Test link</span></Menu>, document.getElementById('menu'))
.menu {
font-weight: bolder;
color: blue;
}
.active{
color:red;
}
<script src="https://cdnjs.cloudflare./ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare./ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="menu" />
本文标签: javascriptReact toggle active class on click of anchor using Gatsby JsStack Overflow
版权声明:本文标题:javascript - React toggle active class on click of anchor using Gatsby Js - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744921152a2632300.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论