目录

效果图片:

具体实现:

 html:

 css:

 JavaScript:


效果图片:

      

具体实现:

 html:

    <!-- 导航栏主体 -->
    <div class="left-menu hide-menu">
        <!-- 顶部标题 -->
        <div>导航栏</div>
        <!-- 链接 -->
        <div class="menu-item-hasChild menu-item">
            <p>菜单一</p>
            <span class="icon">&gt;</span>
        </div>
        <div class="menu-first-items">
            <ul>
                <li>
                    <div class="li-text li-underline">选项一</div>
                </li>
                <li>
                    <div class="li-text li-underline">选项二</div>
                </li>
                <li>
                    <div class="li-text li-underline">选项三</div>
                </li>
                <li>
                    <div class="li-text">选项四</div>
                </li>
            </ul>
        </div>
    
        <div class="menu-no-child menu-item">菜单二</div>
        <div class="menu-no-child menu-item">菜单三</div>
    
        <div class="menu-item-hasChild menu-item">
            <p>菜单四</p>
            <span class="icon">></span>
        </div>
        <div class="menu-first-items">
            <ul>
                <li>
                    <div class="li-text li-underline">选项一</div>
                </li>
                <li>
                    <div class="li-text li-underline">选项二</div>
                </li>
                <li>
                    <div class="li-text li-underline">选项三</div>
                </li>
                <li>
                    <div class="li-text">选项四</div>
                </li>
            </ul>
        </div>
    
        <div class="menu-item-hasChild menu-item">
            <p>菜单五</p>
            <span class="icon">></span>
        </div>
        <div class="menu-first-items">
            <ul>
                <li>
                    <div class="li-text li-underline">选项一</div>
                </li>
                <li>
                    <div class="li-text li-underline">选项二</div>
                </li>
                <li>
                    <div class="li-text li-underline">选项三</div>
                </li>
                <li>
                    <div class="li-text">选项四</div>
                </li>
            </ul>
        </div>
    
        <div class="menu-no-child menu-item">菜单六</div>
    </div>
    <!-- 展开与关闭导航区的模拟按键 -->
    <div class="open-close reverse-condition"> &lt; </div>

 css:

        一级导航标题右侧的小箭头以及控制展开、隐藏导航栏的右侧“按钮”的图标都是用符号“<”来做的,就是html中的&gt; 数学中的交集和并集符号也可以做。利用transform中的变换函数可以将两个边的方向往外拉伸,就不会显得又扁又尖。

        右侧控制导航栏展开和隐藏的模拟按钮,利用3D变换+透视距离来实现一个矩形的效果。

:root {
  font-family: "Courier New", Courier, monospace;
}
* {
  box-sizing: border-box;
  overflow: hidden;
  color: black;
}

.left-menu {
  position: fixed;
  top: 0;
  left: 0;
  width: 175px;
  height: 100vh;
  background-color: rgb(246, 246, 246);
  border-right: 2px solid white;
  text-align: center;
  font-size: 1.2rem;
  transition: left 0.2s linear 0.1s;
}
.hide-menu {
  left: -180px;
}

/** 导航栏 */
.left-menu > div:nth-child(1) {
  margin-top: 2rem;
  margin-bottom: 1.5rem;
  border: 0px;
  font-size: 1.4rem;
  font-weight: 900;
}
/** 全部一级菜单 */
.menu-item {
  padding: 1rem;
  width: 100%;
  font-weight: 800;
  border-radius: 0.3rem;
  border-top: 0.1px solid rgb(201, 195, 195);
  border-bottom: 0.1px solid rgb(201, 195, 195);
}
.menu-item:hover {
  cursor: pointer;
  background-color: rgb(224, 224, 224);
}

/** 可打开的菜单 */
.menu-item-hasChild {
  position: relative;
  align-items: center;
}
.menu-item-hasChild > p {
  margin: 0;
}
.icon {
  position: absolute;
  right: 25px;
  top: 50%;
  font-size: 1rem;
  font-weight: 100;
  transition: transform 0.3s linear;
  transform: translate(0, -50%) rotate(90deg) scaleY(1.8);
  opacity: 0.5;
  z-index: 2;
}

/** 可打开的菜单被点击后icon的样式 */
.reverse-icon {
  transform: translate(0, -50%) rotate(270deg) scaleY(1.8);
}

/** 可打开的菜单的直属列表 */
.menu-first-items {
  height: 0px;
  margin: 0px;
  padding: 0px;
  overflow: hidden;
  transition: height 0.3s ease-out 0.1s;
}
ul {
  margin: 0px;
  padding: 0px;
}
.ul-active {
  height: 140px;
}
li {
  list-style: none;
}
.li-text {
  font-size: 1.1rem;
  line-height: 35px;
  height: 35px;
  width: 70%;
  margin: 0 auto;
}
.li-underline {
  border-bottom: 0.5px solid rgba(104, 104, 104, 0.2);
}
.li-text:hover {
  background-color: rgb(224, 224, 224);
  cursor: pointer;
  border-radius: 0.5rem;
}

/** 展开与关闭导航航 */
.open-close {
  position: fixed;
  padding: 20px;
  font-size: 2rem;
  font-weight: bolder;
  top: 50%;
  left: 156px;
  background-color: rgb(246, 246, 246);
  transition: left 0.2s linear 0.1s, transfrom 0.2s linear 0.1s;
  transform: translate(0, -50%) perspective(100px) rotateY(70deg) scaleY(1.6);
}
.open-close:hover {
  cursor: pointer;
  background-color: rgb(200, 200, 200);
}
.reverse-condition {
  margin: 0;
  left: -20px;
  transform: translate(0, -50%) perspective(100px) rotateY(70deg) scaleY(1.6)
    rotateZ(180deg);
}
.bg-color{
    background-color: #fecc90;
}

 JavaScript:

        1、当某个一级菜单被点击时,控制展开二级菜单和一级菜单右侧的小图标翻转变化
        2、当有一个一级菜单被打开,在其没有被关闭的情况下,又点击另一个一级菜单,则将前一个一级菜单关闭

    let menuItems = document.getElementsByClassName("menu-item-hasChild");
    let items = document.getElementsByClassName("menu-first-items");
    let noChildItem = document.getElementsByClassName('menu-no-child');
    let icons = document.getElementsByClassName("icon");

    /** 记录当前打开的一级菜单是哪个 没有打开任何菜单的状态 默认为-1 */
    let currentDisplayIndex = -1;

    for (let i = 0; i < menuItems.length; i++) {
        menuItems[i].onclick = function () {
            /** 再次点击已打开的菜单,关闭此菜单 */
            if (currentDisplayIndex === i) {
                items[currentDisplayIndex].classList.toggle("ul-active");
                icons[currentDisplayIndex].classList.toggle("reverse-icon");
                menuItems[currentDisplayIndex].classList.toggle('bg-color');
                currentDisplayIndex = -1
                return;
            }

            /** 关闭前一个被打开的菜单 打开当前要打开的菜单 */
            if (currentDisplayIndex != -1) {
                items[currentDisplayIndex].classList.toggle("ul-active");
                icons[currentDisplayIndex].classList.toggle("reverse-icon");
                menuItems[currentDisplayIndex].classList.toggle('bg-color');

                items[i].classList.toggle("ul-active");
                icons[i].classList.toggle("reverse-icon");
                menuItems[i].classList.toggle('bg-color');
            }
            /** 没有任何菜单被打开时 打开新菜单 */
            else{
                items[i].classList.toggle("ul-active");
                icons[i].classList.toggle("reverse-icon");
                menuItems[i].classList.toggle('bg-color');
            }

            // 清除没有下一级列表的菜单的背景
            if(currentDisplayIndex === -1){
                for(let e of noChildItem){
                    if(e.classList.contains('bg-color')){
                        e.classList.toggle('bg-color');
                    }
                }
            }
            
            currentDisplayIndex = i;   
        };
    }

    // 当没有子菜单的菜单被点击
    for(let e of noChildItem){
        e.addEventListener('click',()=>{
            // 处理非同类菜单
            for(let i = 0 ; i < items.length ; i ++){
                if(items[i].classList.contains('ul-active')){
                    items[i].classList.toggle('ul-active');
                    icons[i].classList.toggle('reverse-icon');
                    menuItems[i].classList.toggle('bg-color');
                }
            }
            // 去除其他同类子菜单的背景色
            for(let i = 0 ; i < noChildItem.length ; i ++){
                if(noChildItem[i].classList.contains('bg-color')){
                    noChildItem[i].classList.toggle('bg-color');
                }
            }
            // 为自己添加背景色
            e.classList.toggle('bg-color');
            currentDisplayIndex = -1;
        })
    }

    // 导航栏的显现与隐藏
    let OC = document.getElementsByClassName("open-close")[0];
    let menu = document.getElementsByClassName("left-menu")[0];
    OC.onclick = function () {
        OC.classList.toggle("reverse-condition");
        menu.classList.toggle("hide-menu");
    };

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐