反应多级推送菜单 SCSS 后退按钮不起作用

React Multi-level push menu SCSS Back button not working

我正在开发适用于我网站上的移动用户的多级推送导航菜单。它基于我的 GitHub 帐户上的项目动态创建链接。我使用的推送菜单来自 codepen https://codepen.io/vixxofsweden/pen/xxGGYOE,我试图让它在 React 中工作,而不仅仅是普通的 HTML、CSS。到目前为止,除了后退按钮以外的所有东西都可以。

但具有讽刺意味的是,当我转到页面底部并按“Shell”下的任何空 space 时,它就像一个后退按钮,将我带到上一个菜单.此推送菜单未使用任何 javascript,但如果它能够解决此问题,我愿意使用它。我已经多次尝试解决这个问题,但其中一些 SCSS 对我来说是陌生的。 我的网站使用 React 在 next.js 上 运行。我将在下面附上我的渲染图和 sass。如果您有任何问题或需要更多信息,请告诉我

这是 index.jsx

中的 render()
render() {
    return (
        <div className={`${this.renderCSS()}`}>
            <div className="nav">
                <nav>
                    <a className="mobile-menu-trigger">Open mobile menu</a>
                    {/* <button className={'mobile-menu-trigger'} >Mobile Menu</button> */}
                    <ul className="menu menu-bar">
                        <li>
                            <a className="menu-link menu-bar-link" aria-haspopup="true">Projects</a>
                            <ul className="mega-menu mega-menu--multiLevel">
                                <li className="mobile-menu-back-item">
                                    <a className="menu-link mobile-menu-back-link">Back</a>
                                </li>
                                {Object.keys(this.props.languages).map(language => {
                                    const allProjects = this.props.languages[language];
                                    return (
                                        <li key={language}>
                                            <a className="menu-link mega-menu-link" aria-haspopup="true">{language}</a>
                                            <ul className="menu menu-list">
                                                {allProjects.map((item, index) => {
                                                    const project = this.props.projects[item];
                                                    const openGithubRepo = () => {
                                                        window.open(project.svn_url, "_blank");
                                                    }
                                                    const openGithubPages = () => {
                                                        window.open(`https://ngwessels.github.io/${project.name}/`, "_blank");
                                                    }
                                                    if (project.has_pages) {
                                                        return (
                                                            <li key={project.id}>
                                                                <a className="menu-link menu-list-link"
                                                                    aria-haspopup="true">{project.name}</a>
                                                                <ul className="menu menu-list">
                                                                    <li>
                                                                        <a className="menu-link menu-list-link" onClick={openGithubRepo}>Open Github</a>
                                                                    </li>
                                                                    <li>
                                                                        <a className="menu-link menu-list-link" onClick={openGithubPages}>Visit Live Example</a>
                                                                    </li>
                                                                </ul>
                                                            </li>
                                                        );
                                                    } else {
                                                        return (
                                                            <li key={project.id}>
                                                                <a className="menu-link menu-list-link" onClick={openGithubRepo}>{project.name}</a>
                                                            </li>
                                                        )
                                                    }
                                                })}

                                            </ul>
                                        </li>
                                    )
                                })}

                            </ul>
                        </li>

                        <li>
                            <a className="menu-link menu-bar-link">Static link</a>
                        </li>

                        {/* <li className="mobile-menu-header">
                            <a className="">
                                <span>Home</span>
                            </a>
                        </li> */}
                    </ul>
                </nav>
            </div>
        </div>
    )
}

这里是 styles.scss

      $color-accent:                      black;
  $color-light:                       #ffffff;
  $color-dark:                        black;
  $menu-link-padding:                 20px 25px;
  $breakpoint:                        950px;
  $mega-menu-multiLevel-colWidth:     100/3 + 0%;
  $mobile-menu-back-height:           "calc(1.4em + 40px)";
  $mobile-menu-back-offset:           "calc(0px - (1.4em + 40px))";
  $menu-mobile-width:                 350px;




  // ------------------ SHARED STYLES

  nav {
    ul, li {
      list-style: none;
      padding: 0;
      margin: 0;
    } 
    a {
      display: block;
      text-decoration: none;
      &:hover, &:visited {
        text-decoration: none;
      }
    }
  }
  .nav {
    a {
      font-family: 'Arial Black';
    }
  }

  .menu-bar {
    background: $color-light;
    display: flex;
  }

  .menu-link {
    padding: $menu-link-padding;
    background: $color-light;
    color: $color-accent;
    transition: background .2s, color .2s;
    position: relative;
    z-index: 1;
    &[aria-haspopup="true"] {
      padding-right: 40px;
      &:after {
        content: "";
        background-image: url('https://s3-us-west-2.amazonaws.com/s.cdpn.io/1397521/arrowRight.svg#accent');
        background-size: 14px;
        width: 14px;
        height: 14px;
        font-size:12px;
        position: absolute;
        right: 10px;
        top:50%;
        transform: translateY(-50%);
      }
    }
  }

  .mega-menu-header {
    font-size: 1.2em;
    text-transform: uppercase;
    font-weight: bold;
    color: darken($color-accent, 5%);
  }

  .mega-menu {
    background: $color-light;
    z-index: 10;
  }

  .mega-menu--multiLevel {
    flex-direction: column;
  }


  // ------------------ MEDIA QUERIES

  @media all and (max-width: $breakpoint) {
      
    .nav {
      padding: 20px;
    }
    
    .mobile-menu-trigger, .mobile-menu-header, .mobile-menu-back-item {
      display: block;
    }
    
    .mobile-menu-trigger {
      background: $color-accent;
      color: $color-light;
      border: 0;
      padding: 10px;
      font-size: 1.2em;
      border-radius: 4px;
    }
    
    .mobile-menu-header {
      order: -1;
      background: grey;
      a {
        padding: $menu-link-padding;
        color: $color-light;
        visibility: visible;
      }
    }
    
    .menu-bar {
      flex-direction: column;
      position: fixed;
      top: 0;
      left: -100%;
      height: 100vh;
      width: $menu-mobile-width;
      max-width: $menu-mobile-width;
      max-width: 90%;
      overflow-x: hidden;
      transition: left .3s;
      box-shadow: 1px 0px 2px 0px rgba(0,0,0,0.25);
      background-color: white;
      z-index: 1000;
      > li {
        > [aria-haspopup="true"] {
          ~ ul {
            display: flex;
            flex-direction: column;
            background: $color-light;
            position: absolute;
            left: 100%;
            top: 0;
            max-height: 100vh;
            width: 100%;
            transition: left .3s;
            // Second level
            > li {
              > [aria-haspopup="true"] {
                font-size: 1.2em;
                ~ ul {
                  a {
                    padding-left: 40px;
                  }
                  // Third level
                  > li {
                    > [aria-haspopup="true"] {
                      ~ ul {
                        a {
                          padding-left: 80px;
                        }
                      }
                    }
                  }
                }
              }
            }
            [aria-haspopup="true"] {
              color: $color-dark;
              &:after {
                content: "+";
                background: none;
                font-size: 1em;
                font-weight: normal;
                height: 20px;
                line-height: 1;
              }
              ~ ul {
                max-height: 0px;
                transform-origin: top;
                transform: scaleY(0);
                transition: max-height .1s;
              }
            }
          }
        }
      }
    }
  
    
    .mega-menu-content {
      padding: $menu-link-padding;
    }
    
    .mobile-menu-back-item {
      order: -1;
      z-index: 1000000000;
      a {
        background: tint(grey, 70%);
        color: $color-dark;
        max-height: $mobile-menu-back-height;
        margin-top: $mobile-menu-back-offset;
        pointer-events: none;
        
        &:before {
          z-index: 1000000000;
          content: "";
          width: 14px;
          height: 12px;
          background-image: url('https://s3-us-west-2.amazonaws.com/s.cdpn.io/1397521/arrowLeft.svg#default');
          background-size: 14px;
          margin-right: 10px;
          display: inline-block;
        }
      }
    }
    
    // ------------------------ ALL DEVICES
    
    .mobile-menu-trigger {
      // FUNCTIONALITY: Open mobile menu
      &:focus {
        ~ ul {
          left: 0;
        }
      }
    }
    
    .menu-bar {
      // FUNCTIONALITY: Keep menu open
      &:hover, &:focus-within {
        left: 0;
      }
      > li {
        > [aria-haspopup="true"] {
          // FUNCTIONALITY: Open mega menu
          &:focus {
            ~ ul {
              left: 0;
            }
          }
          ~ ul {
            // STYLING: Back button offset
            margin-top: $mobile-menu-back-height;
        
            // FUNCTIONALITY: Keep mega menu open
            &:hover, &:focus-within {
              left: 0;
            }
            // FUNCTIONALITY: Open dropdowns
            [aria-haspopup="true"] {
              &:focus {
                ~ ul {
                  max-height: 500px;
                  animation: dropdown .3s forwards;
                }
              }
            }
            // FUNCTIONALITY: Keep dropdowns open
            li {
              &:focus-within {
                > [aria-haspopup="true"] {
                  ~ ul {
                    max-height: 500px;
                    transform: scaleY(1);
                  }
                }
              }
            }
            
          }
        }
        // FUNCTIONALITY: Prevent clicks on link behind back button
        // &:focus-within ~ .mobile-menu-header a {
        //   visibility: visible;
        // }
      }
    }
    
    // ------------------------ TOUCH DEVICES
    
    @media (hover: none) {
      
      // FUNCTIONALITY: Open mobile menu 
      .mobile-menu-trigger {
        &:hover {
          ~ ul {
            left: 0;
          }
        }
      }
      
      // FUNCTIONALITY: Open mega menu
      .menu-bar {
        > li {
          > [aria-haspopup="true"] {
            &:hover {
              ~ ul {
                left: 0;
              }
            }
            ~ ul {
              &:hover {
                left: 0;
              }
              // FUNCTIONALITY: Open dropdowns
              [aria-haspopup="true"] {
                &:hover {
                  ~ ul {
                    max-height: 500px;
                    animation: dropdown .3s forwards;
                  }
                }
                ~ ul {
                  &:hover {
                    max-height: 500px;
                    transform: scaleY(1);
                  }
                }
              }
            }
          }
          // &:hover ~ .mobile-menu-header {
          //   a {
          //     visibility: hidden;
          //   }
          // }
        }
      }
    }
  }


  // ------------------ ANIMATIONS

  @keyframes dropdown {
    0% {
      opacity: 0;
      transform: scaleY(0);
    }
    50% {
      opacity: 1;
    }
    100% {
      transform: scaleY(1);
    }
  }

  @keyframes flyout {
    0% {
      opacity: 0;
      transform: scaleX(0);
    }
    100% {
      opacity: 1;
      transform: scaleX(1);
    }
  }

所以我找到了一个涉及使用 javascript 向元素添加样式的解决方案。如果有人找到只涉及添加 css 的解决方案,请告诉我。这是代码:

render() {
    return (
        <div className={`${this.renderCSS()}`}>
            <div className="nav">
                <nav>
                    <a className="mobile-menu-trigger">Open mobile menu</a>
                    <ul className="menu menu-bar" id={'menu-bar'}>
                        <li>
                            <a className="menu-link menu-bar-link" aria-haspopup="true" onClick={() => {
                                const el = document.getElementById('popup');
                                el.style.left = '0';
                            }}>Projects</a>
                            <ul className="mega-menu mega-menu--multiLevel" id={'popup'}>
                                <li className="mobile-menu-back-item">
                                    <a className="menu-link mobile-menu-back-link" onClick={() => {
                                        const el = document.getElementById('popup');
                                        el.style.left = '100%';
                                    }}>Back</a>
                                </li>
                                {Object.keys(this.props.languages).map(language => {
                                    const allProjects = this.props.languages[language];
                                    return (
                                        <li key={language}>
                                            <a className="menu-link mega-menu-link" aria-haspopup="true">{language}</a>
                                            <ul className="menu menu-list">
                                                {allProjects.map((item, index) => {
                                                    const project = this.props.projects[item];
                                                    const openGithubRepo = () => {
                                                        window.open(project.svn_url, "_blank");
                                                    }
                                                    const openGithubPages = () => {
                                                        window.open(`https://ngwessels.github.io/${project.name}/`, "_blank");
                                                    }
                                                    if (project.has_pages) {
                                                        return (
                                                            <li key={project.id}>
                                                                <a className="menu-link menu-list-link"
                                                                    aria-haspopup="true">{project.name}</a>
                                                                <ul className="menu menu-list">
                                                                    <li>
                                                                        <a className="menu-link menu-list-link" onClick={openGithubRepo}>Open Github</a>
                                                                    </li>
                                                                    <li>
                                                                        <a className="menu-link menu-list-link" onClick={openGithubPages}>Visit Live Example</a>
                                                                    </li>
                                                                </ul>
                                                            </li>
                                                        );
                                                    } else {
                                                        return (
                                                            <li key={project.id}>
                                                                <a className="menu-link menu-list-link" onClick={openGithubRepo}>{project.name}</a>
                                                            </li>
                                                        )
                                                    }
                                                })}

                                            </ul>
                                        </li>
                                    )
                                })}

                            </ul>
                        </li>

                        <li>
                            <a className="menu-link menu-bar-link">Static link</a>
                        </li>

                        {/* <li className="mobile-menu-header">
                            <a className="">
                                <span>Home</span>
                            </a>
                        </li> */}
                    </ul>
                </nav>
            </div>
        </div>
    )
}