【问题标题】:Add dropdown to side navbar将下拉菜单添加到侧导航栏
【发布时间】:2017-05-06 02:51:06
【问题描述】:

我正在尝试将 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>
    );
  }
}

【问题讨论】:

    标签: javascript css reactjs


    【解决方案1】:

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

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

    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>

    【讨论】:

      【解决方案2】:

      我对这个问题的建议是阅读 fb react 网站上给出的示例:https://facebook.github.io/react/docs/handling-events.html

      然后在 LeftNav.js 里面:

      为要修改的 UI 组件添加 onClick 函数和 handleClick 函数。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-12-09
        • 1970-01-01
        • 1970-01-01
        • 2017-10-07
        • 2020-09-06
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多