【问题标题】:Full screen responsive menu still clickable when closed全屏响应式菜单在关闭时仍可点击
【发布时间】:2020-10-19 00:49:40
【问题描述】:

我在一个网站上工作,我已经包含了一个全屏菜单,当单击菜单图标时该菜单会出现。但是,我遇到了一个问题,菜单项(按钮)在菜单关闭时仍然可以点击。

我正在使用 React.js + Scss。

const  MyNav = () => {
  const toggleClass = (element, stringClass) => {
        if(element.classList.contains(stringClass))
            element.classList.remove(stringClass);
        else
            element.classList.add(stringClass);
    }

  useEffect(() => {
        const body = document.querySelector('body');
        const menu = document.querySelector('.menu-icon');
    menu.addEventListener('click', () => toggleClass(body, 'nav-active'));
  },[]);
  
  console.log("this is being loaded"); 
  return (
    <>
      <div class="menu-icon">
      <span class="menu-icon__line menu-icon__line-left"></span>
      <span class="menu-icon__line"></span>
      <span class="menu-icon__line menu-icon__line-right"></span>
    </div>

    <div class="nav">
      <div class="nav__content">
        <ul class="nav__list">
          <li class="nav__list-item">Home</li>
          <li class="nav__list-item">About</li>
          <li class="nav__list-item">Portfolio</li>
          <li class="nav__list-item">Journal</li>
          <li class="nav__list-item">Contact</li>
        </ul>
      </div>
    </div>
    </>
  )
}
export default MyNav; 
$font--color:var(--primary);
$font--color--active:var(--primary);
$transition--length: .8;

//default state
.menu-icon{
    $size: 30px;
    height: $size;
    width: $size;
    position: fixed;
    z-index:2;
    left: 50px;
    top: 30px;
    cursor: pointer;
    &__line{
        height: 2px;
        width: $size;
        display: block;
        background-color: $font--color;
        margin-bottom: 4px;
        transition: transform .2s ease, background-color .5s ease;
    }
    &__line-left{
        width: $size / 2;
    }
    &__line-right{
        width: $size / 2;
        float: right;
    }
}

.nav{
    $width: 100vw;
    $height: 100vh;
    $font--size--calc: calc(2vw + 10px);
    $transition--easing: cubic-bezier(.77,0,.175,1);
    position: fixed;
    z-index:1;
    &:before,&:after{
        content: "";
        position: fixed;
        width:$width;
        height:$height;
        background: rgba(#eaeaea, .2);
        z-index: -1;
        transition: transform $transition--easing $transition--length + s;
        transform: translateX(0%) translateY(-100%);
    }
    &:after{
        background: var(--highlight);
        transition-delay: 0s;
    }
    &:before{
        transition-delay: .1s;
    }
    &__content{
        position: fixed;
        top:50%;
        transform: translate(0%,-50%);
        width: 100%;
    text-align: center;
        font-size: $font--size--calc;
        font-weight: 200;
        cursor: pointer;
    }
    &__list-item{
        position: relative;
        display: inline-block;
        transition-delay: $transition--length + s;
        opacity: 0;
        transform: translate(0%, 100%);
        transition: opacity .2s ease, transform .3s ease;
        margin-right: 25px;
        &:before{
            content: "";
            position: absolute;
            background: $font--color--active;
            width: 20px;
            height: 1px;
            top: 100%;
            transform: translate(0%, 0%);
            transition: all .3s ease;
            z-index: -1;
        }
        &:hover{
            &:before{
                width: 100%;
            }
        }
    }
}

//active state
body.nav-active{
    $menu--items--count: 5;
    .menu-icon{
        &__line{
            background-color: var(--primary);
            transform: translateX(0px) rotate(-45deg);
        }
        &__line-left{
            transform: translateX(1px) rotate(45deg);
        }
        &__line-right{
            transform: translateX(-2px) rotate(45deg);
        }
    }
    .nav{
        visibility:visible;
        &:before,&:after{
            transform: translateX(0%) translateY(0%);
        }
        &:after{
            transition-delay: .1s;
        }
        &:before{
            transition-delay: 0s;
        }
        &__list-item{
            pointer-events: all;
            opacity: 1;
            transform: translateX(0%);
            transition: opacity .3s ease, transform .3s ease, color .3s ease;
            @for $i from 0 through $menu--items--count {
                &:nth-child(#{$i}){
                    transition-delay: $transition--length * $i / 8 + .5 + s;
                }
            }
        }
    }
}

如果您能告诉我如何在菜单打开时不让网站滚动,则可以加分。

谢谢!

【问题讨论】:

    标签: javascript html css reactjs web


    【解决方案1】:

    您需要将导航上的visibility 属性设置为hidden,当它像这样不可见时

    .nav{
        $width: 100vw;
        $height: 100vh;
    
        //add this when nav is not active by default
        visibility: hidden;
        transition:visibility .3s cubic-bezier(.77,0,.175,1);
    
        $font--size--calc: calc(2vw + 10px);
        $transition--easing: cubic-bezier(.77,0,.175,1);
        position: fixed;
        z-index:1;
        .
        .
        .
    }
    

    要在菜单打开时移除滚动条,您可以仅使用 .nav-active 类将 overflow 隐藏在主体上

    body.nav-active{
     overflow:hidden;
     $menu--items--count: 5;
        .menu-icon{
     .
     .
     .
    }
    

    希望这会有所帮助!

    【讨论】:

    • 这真的很有帮助,非常感谢!我确实注意到,如果我添加 visibility: hidden; 片段,则结束动画会消失。对此有什么想法吗?
    • @er.gt 更新了答案
    • 喜欢这个? transition: opacity .3s ease, transform .3s ease, color .3s ease, visibility .3s hidden; 我在.nav_active__list-item 部分添加了这个。不确定我是否正确添加了它,因为动画仍然不存在。感谢您的帮助!
    • nav 上。尝试使用transition: all .3s ease;
    • 把我的头撞到墙上已经很久了——非常感谢你。这一切都奏效了!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多