原生JS实现可折叠导航栏

实现效果

在这里插入图片描述

制作过程

首先页面分为两个div,一个导航一个内容。其中内容中需要一个按钮用来控制折叠。


<div class="left-nav"></div>
<div class="cont">
    <button>按钮</button>
</div>

加入样式

.left-nav{
    width:280px;
    height:1000px;
    background:#343A40;
    position: fixed;
    left:0;
    top:0;
    color:rgba(255,255,255,.7);
    font-size: 1.0rem;
    overflow: hidden;
    z-index: 2;
    white-space:nowrap;
}
.cont{
    width:auto;
    margin-left:280px;
    min-width: 1050px;
}

折叠效果是通过触发事件后,循环改变nav的宽度和cont的左边距实现cont盖住nav的视觉效果。但在代码中,并不能真的用for循环来做,那样在移动过程中js就会一直卡在循环中而不能执行其他代码,所以这里可以使用setInterval函数来做,它会每隔一段时间调用一次某个方法,格式为setInterval(调用函数,调用间隔时间,调用函数参数1,参数2,...);当任务完成时再通过clearInterval函数结束循环调用。
为了使移动更平滑,每次调用时只移动到目标位置之间的距离的10%.实现折叠的函数代码如下:

/*关闭/打开导航*/
function closeNav(nav,body,navTargetWidth){
    var thisTarget = nav.getBoundingClientRect().width + (navTargetWidth - nav.getBoundingClientRect().width)*0.1;    //这次目标宽度
    nav.style.width = (Math.abs(thisTarget-navTargetWidth)<0.5?navTargetWidth:thisTarget) + "px";
    body.style.marginLeft = nav.style.width;
    if(nav.getBoundingClientRect().width == navTargetWidth){
        clearInterval(CWLN);
    }
}

调用时机为触发指定事件时调用,这里事件分为,点击按钮,鼠标进入导航栏,鼠标移出导航栏三种。
当点击按钮后,判断当前导航栏是收缩还是展开状态,如果是收缩状态就将导航栏的宽和内容块的左外边距逐渐增长为展开时的值,反之同理。而判断是通过一个变量来标识导航栏状态实现。

var leftNavIsClose = false;
var leftNav = document.getElementsByClassName("left-nav")[0];
var body = document.getElementsByClassName("body")[0];
var minWidth_leftNav = 60;
var maxWidth_leftNav = 280;
CWLN = null;
document.getElementById("close-left-nav").onclick = function(){
    if(leftNavIsClose)
        CWLN = setInterval(closeNav,10,leftNav,body,maxWidth_leftNav);
    else
        CWLN = setInterval(closeNav,10,leftNav,body,minWidth_leftNav);
    leftNavIsClose = !leftNavIsClose;
}

当鼠标进入和离开导航栏时:

document.getElementsByClassName("left-nav")[0].onmouseenter = function(){
    clearInterval(CWLN);
    CWLN = setInterval(closeNav,10,leftNav,body,maxWidth_leftNav);
}
document.getElementsByClassName("left-nav")[0].onmouseleave = function(){
    if(leftNavIsClose){
        clearInterval(CWLN);
        CWLN = setInterval(closeNav,10,leftNav,body,minWidth_leftNav);
    }
}

效果
在这里插入图片描述

完整源码

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <style>
            .left-nav{
                width:280px;
                height:1000px;
                background:#343A40;
                position: fixed;
                left:0;
                top:0;
                color:rgba(255,255,255,.7);
                font-size: 1.0rem;
                overflow: hidden;
                z-index: 2;
            }
            .body{
                width:auto;
                margin-left:280px;
                min-width: 1050px;
            }
        </style>
    </head>
    <body>
        <div class="left-nav">导航&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;导航导航</div>
        <div class="body">
            <button id="close-left-nav">按钮</button><br/>
            内容内容内容
        </div>
    </body>
    <script>
        /*关闭/打开导航*/
        function closeNav(nav,body,navTargetWidth){
            var thisTarget = nav.getBoundingClientRect().width + (navTargetWidth - nav.getBoundingClientRect().width)*0.1;    //这次目标宽度
            nav.style.width = (Math.abs(thisTarget-navTargetWidth)<0.5?navTargetWidth:thisTarget) + "px";
            body.style.marginLeft = nav.style.width;
            if(nav.getBoundingClientRect().width == navTargetWidth){
                clearInterval(CWLN);
            }
        }
        var leftNavIsClose = false;
        var leftNav = document.getElementsByClassName("left-nav")[0];
        var body = document.getElementsByClassName("body")[0];
        var minWidth_leftNav = 60;
        var maxWidth_leftNav = 280;
        CWLN = null;
        document.getElementById("close-left-nav").onclick = function(){
            if(leftNavIsClose)
                CWLN = setInterval(closeNav,10,leftNav,body,maxWidth_leftNav);
            else
                CWLN = setInterval(closeNav,10,leftNav,body,minWidth_leftNav);
            leftNavIsClose = !leftNavIsClose;
        }
        document.getElementsByClassName("left-nav")[0].onmouseenter = function(){
            clearInterval(CWLN);
            CWLN = setInterval(closeNav,10,leftNav,body,maxWidth_leftNav);
        }
        document.getElementsByClassName("left-nav")[0].onmouseleave = function(){
            if(leftNavIsClose){
                clearInterval(CWLN);
                CWLN = setInterval(closeNav,10,leftNav,body,minWidth_leftNav);
            }
        }
    </script>
</html>
本文作者:六月丶

本文链接:https://hctra.cn/index.php/archives/667/

版权声明:如无特别声明,本文即为六月'blog原创,仅代表个人观点,如要转载请务必注明文章出处。
最后修改:2020 年 09 月 22 日 02 : 58 PM
如果觉得我的文章对你有用,请随意赞赏

发表评论

1 条评论

  1. 金石热点网

    文章写的不错,加油~