javascript - 将下拉菜单添加到侧边导航栏

标签 javascript css reactjs

我正在尝试将 onClick 添加到我的导航栏下拉图标(箭头)和将显示和取消显示社交网络的“Drop”标题,并带有滑动动画。

所以想象一下,首先假设只有电话、箭头和用户图标/w 标题,当您单击箭头时,社交网络图标和文本会向下滑动。

这是我到目前为止所取得的成就:

http://codepen.io/apswak/full/jVJmxV/

有人知道我写的方式是否可行吗?如果可以,我该如何实现?

谢谢

PS:我是用react写的,代码如下:

LeftNav.js:

import NavIcons from './NavIcons'
import NavText from './NavText'
import NavInfo from './NavInfo'

export default class Navbar extends Component {
  render() {
    return (
      <div id="nav" className="nav">
            <NavIcons/>
            <NavText/>
            <NavInfo/>
        </div>
    )
  }
}

NavIcons.js:

import { Link } from 'react-router'

export default class NavIcons extends Component {
  render() {
    return (
      <div className="icon">
        <ul>
          <li className="main-nav-btn"><Link to="/"><i className="fa fa-table"></i></Link></li>
          <li className="main-nav-btn"><Link to="/"><i className="fa fa-line-chart"></i></Link></li>
          <li className="sub-nav-btn"><Link to="/#/fb"><i className="fa fa-facebook fb-col"></i></Link></li>
          <li className="sub-nav-btn"><Link to="/#/twit"><i className="fa fa-twitter twit-col"></i></Link></li>
          <li className="sub-nav-btn"><Link to="/#/ig"><i className="fa fa-instagram ig-col"></i></Link></li>
          <li className="sub-nav-btn"><Link to="/#/ga"><i className="fa fa-google ga-col"></i></Link></li>
          <li className="main-nav-btn"><Link to="/#"><i className="fa fa-object-group"></i></Link></li>
          <li className="main-nav-btn"><Link to="/#"><i className="fa fa-camera-retro"></i></Link></li>
        </ul>
      </div>
    )
  }
}

NavInfo.js:

export default class NavInfo extends Component {
  render() {
    return (
      <div class="info">
        <img width="50px"
          alt="Logo" src="https://upload.wikimedia.org/wikipedia/commons/thumb/b/b6/Cool_TV_logo_2004.svg/2000px-Cool_TV_logo_2004.svg.png"
          class="navbar-logo"/>
        <div class="row">
          <div class="social">
            <a target="_blank" href="https://www.facebook.com/"><i class="fa fa-facebook tang-nav-social"></i></a>
            <a target="_blank" href="https://www.instagram.com"><i class="fa fa-instagram tang-nav-social"></i></a>
          </div>
        </div>
      </div>
    )
  }
}

NavText.js:

export default class NavText extends Component {
  render () {
    return (
      <div class="text">
        <ul>
          <li class="main-nav-btn"><a href="#">Call</a></li>
          <li class="main-nav-btn"><a href="#">Drop</a></li>
          <li class="sub-nav-btn fb-col"><a href="#">Facebook</a></li>
          <li class="sub-nav-btn"><a href="#">Twitter</a></li>
          <li class="sub-nav-btn ig-col"><a href="#">Instagram</a></li>
          <li class="main-nav-btn"><a href="#">Title</a></li>
        </ul>
      </div>
    );
  }
}

最佳答案

我使用您在 Codepen 上的基本代码进行设置。如果您运行该代码段,它应该在下面运行良好。我为您添加了两个 CSS 类,并向您的两个需要隐藏元素的组件发送了一个事件处理程序 prop。我将顶层元素更改为有状态的,以便它可以管理各种组件的 CSS 类中的更改。更改了一些小的东西以使其在 SO 代码段环境中工作所以看看我对您的组件和一些 JSX 所做的具体更改,您应该能够很容易地使其适应您的代码。

我没有时间为您设置动画,但最简单的方法可能是 jQuery .show().hide()即使将它与 react 一起使用并不理想。使用纯 react (理想方式)你会设置一个 <ReactCSSTransitionGroup />

More info on that here

这有点挑战性,但您应该能够在您当前的代码库中正常工作,并对我为您所做的稍作修改。

class App extends React.Component {
  render() {
    return (
      <Navbar />
    );
  }
}

class Navbar extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      swtichClass: 'drop-menu drop-hide',
    };
    this.changeClass = this.changeClass.bind(this);
  }
  changeClass() {
    if(this.state.swtichClass === 'drop-menu drop-hide') {
      this.setState({swtichClass: 'drop-menu'});
    } else {
      this.setState({swtichClass: 'drop-menu drop-hide'});
    }
  }
  render() {
    return (
      <div id="nav" className="nav">
            <NavIcons classState={this.state.swtichClass} changeClass={this.changeClass} />
            <NavText classState={this.state.swtichClass} changeClass={this.changeClass} />
            <NavInfo/>
        </div>
    );
  }
}
class NavIcons extends React.Component {
  constructor(props){
    super(props);
    this.chevSwitch = this.chevSwitch.bind(this);
  }
  chevSwitch() {
    if(this.props.classState === 'drop-menu drop-hide'){
      return 'fa fa-chevron-circle-right';
    } else {
      return 'fa fa-chevron-circle-down';
    }
  }
  render() {
    return (
      <div className="icon">
        <ul>
          <li className="main-nav-btn"><a href="#"><i className="fa fa-phone"></i></a></li>
          <li className="main-nav-btn" onClick={this.props.changeClass}><a href="#"><i className={this.chevSwitch()}></i></a></li>
          <div className={this.props.classState}>
          <li className="sub-nav-btn"><a href="#"><i className="fa fa-facebook fb-col"></i></a></li>
          <li className="sub-nav-btn"><a href="#"><i className="fa fa-twitter twit-col"></i></a></li>
          <li className="sub-nav-btn"><a href="#"><i className="fa fa-instagram ig-col"></i></a></li>
          </div>
          <li className="main-nav-btn"><a href="#"><i className="fa fa-user-circle"></i></a></li>
        </ul>
      </div>
    );
  }
}
class NavInfo extends React.Component {
  render() {
    return (
      <div className="info">
        <img width="50px"
          alt="Logo" src="https://upload.wikimedia.org/wikipedia/commons/thumb/b/b6/Cool_TV_logo_2004.svg/2000px-Cool_TV_logo_2004.svg.png"
          className="navbar-logo"/>
        <div className="row">
          <div className="social">
            <a target="_blank" href="https://www.facebook.com/"><i className="fa fa-facebook tang-nav-social"></i></a>
            <a target="_blank" href="https://www.instagram.com"><i className="fa fa-instagram tang-nav-social"></i></a>
          </div>
        </div>
      </div>
    );
  }
}
class NavText extends React.Component {
  constructor(props){
    super(props);
  }
  render () {
    return (
      <div className="text">
        <ul>
          <li className="main-nav-btn"><a href="#">Call</a></li>
          <li className="main-nav-btn" onClick={this.props.changeClass}><a href="#">Drop</a></li>
          <div className={this.props.classState}>
          <li className="sub-nav-btn fb-col"><a href="#">Facebook</a></li>
          <li className="sub-nav-btn"><a href="#">Twitter</a></li>
          <li className="sub-nav-btn ig-col"><a href="#">Instagram</a></li>
          </div>
          <li className="main-nav-btn"><a href="#">Title</a></li>
        </ul>
      </div>
    );
  }
}
ReactDOM.render(
  <App />,
  document.getElementById('root')
);
@import url('https://fonts.googleapis.com/css?family=Lato');
body {
  padding: 0;
  margin: 0;
  height: 100vh;
  width: 100vh;
  background-color: red;
  font-family: 'Lato', sans-serif;
}
.drop-hide {
  display:none !important;
}
.drop-menu {
  display: block;

}
.nav {
  height: 100%;
  position: fixed;
  left: -2em;
  top: 0;
  padding-top: 150px;
  -webkit-transform-style: preserve-3d;
          transform-style: preserve-3d;
  -webkit-perspective: 1000px;
          perspective: 1000px;
}
.navbar-logo {
  position: relative;
  margin-bottom: 50px;
  /*right: 0;
  left: 0;
  margin: 0 auto;*/
}
.fb-col {
  color: #3B5998 !important;
}
.twit-col {
  color: #1DA1F2 !important;
}
.ig-col {
  color: #635AC8 !important;
}
.nav .icon .circle {
  position: absolute;
  border: solid 1px #222;
  margin-top: -18px;
  right: 20px;
  width: 8px;
  height: 8px;
  border-radius: 4px;
}
.nav .icon {
  position: absolute;
  left: 0;
  top: 0;
  z-index: 990;
  height: 100%;
  background: #4c4c4c; /* Old browsers */
  background: -moz-linear-gradient(top,  #4c4c4c 0%, #000000 0%, #000000 10%, #1c1c1c 91%, #2c2c2c 100%, #111111 100%, #131313 100%); /* FF3.6-15 */
  background: -webkit-linear-gradient(top,  #4c4c4c 0%,#000000 0%,#000000 10%,#1c1c1c 91%,#2c2c2c 100%,#111111 100%,#131313 100%); /* Chrome10-25,Safari5.1-6 */
  background: linear-gradient(to bottom,  #4c4c4c 0%,#000000 0%,#000000 10%,#1c1c1c 91%,#2c2c2c 100%,#111111 100%,#131313 100%); /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */
  filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#4c4c4c', endColorstr='#131313',GradientType=0 ); /* IE6-9 */

}
.nav .icon li {
  border-bottom: 1px solid rgba(0, 0, 0, 0.3);
  list-style-type: none;
}
.nav .icon a {
  display: block;
  width: 64px;
  text-align: center;
  color: whitesmoke;
  text-shadow: 0 1px 0 black;
  -webkit-transition: all .5s ease-out;
  transition: all .5s ease-out;
}
.main-nav-btn {
  height: 64px;
  line-height: 64px;
  font-size: 1.3em;
}
.sub-nav-btn {
  height: 40px;
  line-height: 40px;
  font-size: 1.1em;
}
.nav .icon a:hover {
  color: white;
}
.nav:hover .text {
  -webkit-transform: rotateY(0deg);
          transform: rotateY(0deg);
}
.nav .text {
  position: absolute;
  left: 63px;
  top: 0;
  z-index: 980;
  width: 160px;
  height: 100%;
  background: #4c4c4c; /* Old browsers */
  background: -moz-linear-gradient(top,  #4c4c4c 0%, #000000 0%, #000000 10%, #1c1c1c 91%, #2c2c2c 100%, #111111 100%, #131313 100%); /* FF3.6-15 */
  background: -webkit-linear-gradient(top,  #4c4c4c 0%,#000000 0%,#000000 10%,#1c1c1c 91%,#2c2c2c 100%,#111111 100%,#131313 100%); /* Chrome10-25,Safari5.1-6 */
  background: linear-gradient(to bottom,  #4c4c4c 0%,#000000 0%,#000000 10%,#1c1c1c 91%,#2c2c2c 100%,#111111 100%,#131313 100%); /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */
  filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#4c4c4c', endColorstr='#131313',GradientType=0 ); /* IE6-9 */

  border-right: 1px solid rgba(0, 0, 0, 0.3);
  -webkit-transition: -webkit-transform .24s linear;
  transition: -webkit-transform .24s linear;
  transition: transform .24s linear;
  transition: transform .24s linear, -webkit-transform .24s linear;
  -webkit-backface-visibility: hidden;
          backface-visibility: hidden;
  -webkit-transform-origin: left;
          transform-origin: left;
  -webkit-transform: perspective(1000px) translateX(-200px);
          transform: perspective(1000px) translateX(-200px);
}
.nav .text li {
  border-bottom: 1px solid rgba(0, 0, 0, 0.3);
}
.nav .text a {
  display: block;
  text-indent: 1em;
  text-decoration: none;
  color: whitesmoke;
  text-shadow: 0 1px 0 black;
  -webkit-transition: all .5s ease;
  transition: all .5s ease;
}
.nav .text .main-nav-btn {
  height: 64px;
  line-height: 64px;
  font-size: 1em;
}
.nav .text .sub-nav-btn {
  height: 40px;
  line-height: 40px;
  font-size: 0.8em;
}
.nav .text a:hover {
  color: white;
  -webkit-transform: translateX(-8px);
          transform: translateX(-8px);
}
.nav:hover .info {
  left: 0;
  opacity: 1;
  -webkit-transition: opacity 0.5s ease-in 0.1s;
  transition: opacity 0.5s ease-in 0.1s;
  width: 150px;
  margin-left: 50px;
}
.nav .info {
  position: absolute;
  bottom: 165px;
  z-index: 998;
  color: white;
  text-align: center;
  line-height: 1.6;
  opacity: 0;
}
.nav .info .logo p {
  width: 100px;
  height: 100px;
  margin: 0 auto;
  background: #4c4c4c; /* Old browsers */
  background: -moz-linear-gradient(top,  #4c4c4c 0%, #000000 0%, #000000 10%, #1c1c1c 91%, #2c2c2c 100%, #111111 100%, #131313 100%); /* FF3.6-15 */
  background: -webkit-linear-gradient(top,  #4c4c4c 0%,#000000 0%,#000000 10%,#1c1c1c 91%,#2c2c2c 100%,#111111 100%,#131313 100%); /* Chrome10-25,Safari5.1-6 */
  background: linear-gradient(to bottom,  #4c4c4c 0%,#000000 0%,#000000 10%,#1c1c1c 91%,#2c2c2c 100%,#111111 100%,#131313 100%); /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */
  filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#4c4c4c', endColorstr='#131313',GradientType=0 ); /* IE6-9 */

  color: #424242;
  opacity: .6;
  overflow: hidden;
  text-align: center;
  -webkit-transition: all .5s ease;
  transition: all .5s ease;
  font-size: 2em;
  text-shadow: -1px -1px #4f4f4f, 1px 1px #121212;
}
.nav .info .logo p:hover {
  opacity: 1;
  color: white;
  text-shadow: -1px -1px #575757, 1px 1px #121212;
}
.nav .info .name {
  font-size: 1.4em;
  font-weight: bold;
  letter-spacing: 2px;
  color: #E98300;
}
.nav .info .kicker {
  font-size: 0.8em;
  font-weight: bold;
  letter-spacing: 2px;
  color: whitesmoke;
}
.nav .info .quote {
  font-size: 0.7em;
  color: lightgrey;
  text-shadow: 1px 1px #121212;
}
.social {
  display: inline-block;
}
.social a {
  color: red;
}
.nav .info .social a {
  font-size: 2em;
  letter-spacing: .5em;
  -webkit-transition: all .5s ease;
  transition: all .5s ease;
}
.nav .info .social a:hover {
  color: whitesmoke !important;
  /*text-shadow: -1px -1px #222, 1px 1px #333;*/
}
.tang-nav-social {
  color: #222;
  cursor: pointer;
}
.tang-nav-social: hover {
  cursor: pointer;
  color: whitesmoke;
}
@media screen and (max-height: 550px) {
  .nav .info {
    display: none;
  }
}
@media screen and (max-width: 450px) {
  .nav h1 {
    font-size: 7.5vw;
  }
}
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
    
    <title>React App</title>
    <link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
  </head>
  <body>
    <div id="root"></div>
  </body>
</html>

关于javascript - 将下拉菜单添加到侧边导航栏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41249933/

相关文章:

javascript - IE9 “tearing” 滚动 block 后面的背景图像具有背景透明度

javascript - Bootstrap 轮播下一个和上一个功能不起作用,仅显示第一个图像

javascript - npm run-script ssr(服务器端渲染不起作用)

javascript - React Material-ui Datepicker/Timepicker OnChange事件回调函数封装

javascript - 我如何在 jQuery 插件代码中执行回调

javascript - fullCalendar删除的事件再次出现,按下按钮更改月份

html - 使用CSS创建多个占据父级整个宽度的元素

CSS 下拉菜单级别

javascript - 回调在 React 中不起作用

javascript - 在 react 中,我如何强制浏览器要求保存密码?