【问题标题】:How do I position my React hamburger menu flush at the upper right of my site?如何将我的 React 汉堡菜单齐平放在网站的右上角?
【发布时间】:2020-05-05 02:10:28
【问题描述】:

我想构建一个汉堡菜单以显示在我的 React 16.13.0 应用的移动版本上。我正在关注本教程——https://www.zacwillmington.com/how-to-add-a-hamburger-menu-to-your-website/。所以我像这样创建了我的导航栏组件

import React, { Component } from 'react';
import { NavLink } from 'react-router-dom';
import HamburgerMenu from 'react-hamburger-menu';
import {isMobile} from 'react-device-detect';
import './NavBar.css';

class NavBar extends Component {
    constructor(){
        super()
        this.state = {
            open: false,
            hideOrShowHambugerDropDown: 'nav'
        }
    }

    handleClick = () => {
        this.setState({open: !this.state.open});
    }

    displayHamburgerMenu = () => {
        return (
            <HamburgerMenu
                    isOpen={this.state.open}
                    menuClicked={this.handleClick.bind(this)}
                    width={18}
                    height={15}
                    strokeWidth={1}
                    rotate={0}
                    color='black'
                    borderRadius={0}
                    animationDuration={0.5}
                />
        )
    }

    displayNavBar = () => {
        return (
            <ul className='nav'>
                    <li className='nav-link'><NavLink to='/add'>Add</NavLink></li>
                    <li className='nav-link'><NavLink to='/search'>Search</NavLink></li>
                </ul>
        )
    }

    displayMobileMenu = () => {
        return (
            <ul className='hamburgerDropDown'>
                    <li className='nav-link'><NavLink to='/add'>Add</NavLink></li>
                    <li className='nav-link'><NavLink to='/search'>Search</NavLink></li>
                </ul>
        )
    }

    render() {
        return (
            <div className='navbar'>
                { this.state.open ? this.displayMobileMenu() : null}
                {isMobile ? this.displayHamburgerMenu() : this.displayNavBar()}
            </div>
        );
    }
}

export default NavBar;

我正在使用这个样式表来控制它...

.hamburgerDropDown {
  background-color: black;
  border: 1px solid bisque;
}

ul.hamburgerDropDown {
  padding: 10px;
}

.navbar div {
  display: inline-block;
}

但是,我遇到了几个问题。菜单没有出现在我的窗口右上角。此外,关闭“x”按钮出现在菜单下方。如何调整这些项目?如果您使用的是移动浏览器,您可以在 http://prod.chicommons.coop/ 看到演示,否则,请参见下文

编辑:如果你有兴趣,这里是 GitHub 上的代码——https://github.com/chicommons/maps/tree/master/client

【问题讨论】:

  • 看起来你在菜单之后渲染菜单切换,所以如果没有绝对/固定定位,它会在菜单打开时渲染。是否可以共享一个正在运行的代码框来解决任何进一步的问题,例如您希望菜单切换的物理位置(右上角)?在屏幕截图中很难分辨,因为它看起来像是全部放大了。
  • 感谢@DrewReese 的分析。如果对我的问题的编辑有用,我会提供一个 GitHub 链接。

标签: css reactjs css-position hamburger-menu


【解决方案1】:

你需要做一些小改动

在汉堡包下拉类中,需要添加 position: absolute 和 top and right 属性

.hamburgerDropDown {
  background-color: black;
  border: 1px solid bisque;
  position: absolute;
  top: 50px;
  right: -1rem;
}

其次,在 Navbar.js 组件中,需要对 Hamburger 和 menu 的渲染重新排序

 handleSelect = () => {
    this.setState({ open: false });
  };
  displayMobileMenu = () => {
    return (
      <ul className="hamburgerDropDown" onClick={this.handleSelect}>
        <li className="nav-link">
          <NavLink to="/add">Add</NavLink>
        </li>
        <li className="nav-link">
          <NavLink to="/search">Search</NavLink>
        </li>
      </ul>
    );
  };
render() {
    return (
      <div className="navbar">
        {isMobile ? this.displayHamburgerMenu() : this.displayNavBar()}  // this rendered before menu
        {this.state.open ? this.displayMobileMenu() : null}
      </div>
    );
  }

Working demo created based on your github project

【讨论】:

  • 谢谢。我相信我复制了您的代码,但我仍然看到一些问题。菜单的右边缘和屏幕的右边缘之间似乎有一个间隙——imgur.com/a/clyon88。此外,当我单击菜单项时,菜单仍然存在(它不会像预期的那样消失)。
  • @Dave 将菜单稍微向右或向左定位只是 css。我相信你能做到。我将更新第二部分的答案
  • @Dave 我已经更新了演示,以处理侧间隙以及导航栏菜单上的选择关闭
  • 谢谢!这看起来运作良好。打算再进行一些测试,但会回来接受。
【解决方案2】:

查看了您的 GitHub。你的开端很好,而且肯定朝着一个好的方向前进。也就是说,有一些领域可以使用一些爱。

构建和架构

您的类组件中有几个功能组件。我建议出于可扩展性和可维护性目的提取这些内容。

注意:在进行这些更新时,您可以通过用括号而不是方括号来包装内容来自动返回粗箭头函数。

注意:您可能需要考虑将组件特定内容(.js、.css、.test.js 等)分组到它们自己的目录中。

汉堡菜单

const HamburgerMenu = () => (
    <HamburgerMenu
        isOpen={this.state.open}
        menuClicked={this.handleClick.bind(this)}
        width={18}
        height={15}
        strokeWidth={1}
        rotate={0}
        color='black'
        borderRadius={0}
        animationDuration={0.5}
    />
);

桌面导航

const DesktopNav = () => (
    <ul className='nav'>
        <li className='nav-link'><NavLink to='/add'>Add</NavLink></li>
        <li className='nav-link'><NavLink to='/search'>Search</NavLink></li>
    </ul>
);

移动菜单

const MobileMenu = () => (
    <ul className='hamburgerDropDown'>
        <li className='nav-link'><NavLink to='/add'>Add</NavLink></li>
        <li className='nav-link'><NavLink to='/search'>Search</NavLink></li>
    </ul>
);

导航栏

您现在可以导入各个组件。此外,因为您除了在constructor 中设置state 之外什么都不做,您实际上可以将其从构造函数中拉出并在类级别设置。在实现新组件时,您可以像调用任何其他组件一样调用它们,而不是实例化函数。

_注意:我还继续将您的div 组件更新为更具语义和可访问性的nav 组件。

import React, { Component } from 'react';
import { NavLink } from 'react-router-dom';
import HamburgerMenu from 'react-hamburger-menu';
import {isMobile} from 'react-device-detect';

import HamburgerMenu from './HamburgerMenu';
import DesktopNav from './DesktopNav';
import MobileMenu from './MobileMenu';

import './NavBar.css';

class NavBar extends Component {
    state = {
        open: false,
        hideOrShowHambugerDropDown: 'nav'
    }

    handleClick = () => {
        this.setState({open: !this.state.open});
    }

    render() {
        return (
            <nav className='navbar'>
                { this.state.open ? <MobileMenu /> : null}
                {isMobile ? <HamburgerMenu /> : <DesktopNav />}
            </nav>
        );
    }
}

造型

现在关于样式的问题。由于父组件的样式,您的内容位于应有的位置。您可以在header 周围调整padding,并利用margin 将组件“推”到您需要的地方。或者,正如@drew-reese 提到的,您可以使用position(absolute 或fix,取决于您想要什么)将图标放在右上角。

另外,请记住,Bootstrap CSS 可能会影响组件的布局。您可能需要在各个组件中覆盖 Bootstrap 设置的样式。

【讨论】:

  • 您好,感谢您的周到回答。我喜欢你如何将 DesktopNav 和 MobileNav 分成两个组件,唯一的一点是这略微增加了可维护性。最终,我想达到一个只有一个导航标题和链接列表的地方,而不必在两个地方维护它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-11-15
  • 2020-07-10
  • 1970-01-01
  • 1970-01-01
  • 2018-05-18
  • 2017-04-06
  • 1970-01-01
相关资源
最近更新 更多