Web 前端开发 程序员前端开发那些事

自适应导航条js原生版

2016-06-04  本文已影响1443人  小pxu

自适应导航条js原生版

看到bootstrap等第三方库中的导航条非常简单好用,没想到自己用原生试着实现用了这么多行代码😳

效果如下:





实现思路:

html+css:
  1. 最外层nav宽度100%。高给固定值
  2. 中间内容部分全部用一个div包裹,宽度百分比,margin: 0 auto; 实现居中
  3. 左侧的logo图片外包div,给的固定宽高
  4. 中间的navbar包裹ul列表用的百分比宽度,使其宽度能够在屏幕缩放的时候随之变化
  5. 右侧按钮部分隐藏
  6. 媒体查询屏幕宽度<768px时,将navbar定位至nav下方,高度给0,并将按钮显示
js:
  1. 用布尔值作为开关控制点击状态
  2. 先设置bol = true,让判断走if语句
  3. 点击一次后,定时器执行navbar和nav的高度增大至预设值,关闭定时器
  4. 定时器后将bol改为false,这样下次点击就会执行else中语句
  5. else中定时器控制nav及navbar高度减小至预设值,关闭定时器
  6. 定时器后将bol再改为true,这样下次点击就会执行if中语句
遇到的坑:

遇到的比较棘手的问题就是开关状态、点击事件、定时器到底该如何嵌套,不过最后还是把思路理清楚了

  1. 先用布尔值判定是走if语句(高度+)还是else语句(高度-)
  2. 再到点击按钮
  3. 点击按钮后再触发定时器
  4. 高度变化至设定值时关闭定时器,及改变布尔值

还有个问题就是因为navbar定位之后失去了撑开下方区块的功能,最后只能将父级nav的高度同步增大,不知道是不是有点绕了

上代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>自适应导航栏</title>
    <style>
        /*简单清除默认样式*/
        * {
            margin: 0;
            padding: 0;
        }
        
        /*导航宽屏时主体部分*/
        nav {
            width: 100%;
            height: 50px;
            background-color: #444;
            overflow: hidden;
            min-width: 320px;
        }
        .nav {
            max-width: 80%;
            margin: 0 auto;
            height: 50px;
        }
        .logo {
            width: 50px;
            height: 50px;
            float: left;
        }
        .logo img {
            width: 100%;
            display: block;
        }

        .navbar {
            width: 80%;
            height: 50px;
            float: right;
        }
        .navbar ul {
            list-style: none;
            height: 50px;
            overflow: hidden;
            float: right;
        }
        .navbar li {
            height: 50px;
            float: left;
            padding: 0 10px;
        }
        .navbar a {
            display: block;
            width: 100%;
            height: 50px;
            line-height: 50px;
            text-decoration: none;
            text-align: center;
            color: #fff;
            font-size: 16px;
            font-weight: bold;
        }
        
        /*媒体查询屏幕宽度小于768px时生效以下效果*/
        @media screen and (max-width: 768px) {
            /*
                1、navbar定位到nav下方,宽度撑满屏幕
                2、高度给成0
                3、超出部分不显示
                4、其他样式相应调整
            */
            .navbar {
                float: right;
                position: absolute;
                top: 50px;
                left: 0;
                width: 100%;
                height: 0px;
                background-color: #444;
                overflow: hidden;
            }
            .navbar ul {
                width: 100%;
                height: 200px;
            }
            .navbar li {
                width: 80%;
                margin: 0 auto;
                float: none;
            }
            .navbar a { text-align: left; }
        }
        
        /*按钮部分,宽屏时是隐藏的*/
        .btn {
            border: 0;
            border-radius: 5px;
            margin-top: 5px;
            width: 40px;
            height: 40px;
            background-color: #aaa;
            float: right;
            display: none;
            opacity: 0.8;
            transition: all 0.5s;
            cursor: pointer;
        }
        .btn:hover { opacity: 1; }
        .btn span {
            display: block;
            width: 60%;
            height: 5px;
            border-radius: 5px;
            margin: 6px 20%;
            background-color: #fff;
        }
        
        /*媒体查询屏幕宽度小于768px时,按钮出现*/
        @media screen and (max-width: 768px) {
            .btn { display: block; }
        }
        
        /*内容部分*/
        .content{
            width: 100%;
            height: 500px;
            background-color: #ddd;
            /*overflow: hidden;*/
        }
        .content h2{
            width: 80%;
            margin: 0 auto;
            height: 50px;
            line-height: 50px;
            text-align: center;
            font-size: 60px;
            color: #fff;
            padding-top: 50px;
        }
        @media screen and (max-width: 768px) {
            .content h2{
                font-size: 40px;
            }
        }
    </style>
</head>
<body>
    <nav>
        <div class="nav">
            <div class="logo">[站外图片上传中……(5)]</div>
            <div id="btn" class="btn">
                <span></span>
                <span></span>
                <span></span>
            </div>
            <div id="navbar" class="navbar">
                <ul>
                    <li><a href="#">首页</a></li>
                    <li><a href="#">公司简介</a></li>
                    <li><a href="#">产品介绍</a></li>
                    <li><a href="#">联系方式</a></li>
                </ul>
            </div>  
        </div>  
    </nav>
    <div id="content" class="content">
        <h2>这是下方内容</h2>
    </div>
</body>
<script>
    
    //获取节点
    var btn = document.getElementById('btn');
    var navbar = document.getElementById('navbar');
    var nav = document.getElementsByTagName('nav')[0];

    //设置布尔值作为开关
    var bol = true;

    //设置定时器
    var timer = null;

    //设定navbar(就是会移到下方的部分)
    var t = navbar.offsetHeight;
    var maxH = 200;
    var minH = 0;

    //设定nav(就是最外面的父级)
    //因为navbar已经定位,所以他无法将下方内容顶开,所以需要同时变更父级的高度来顶开下方内容
    var navT = nav.offsetHeight;
    var navMaxH = 250;
    var navMinH = 50;

    btn.onclick = function () {
        
        // 判定布尔值
        if (bol){
            
            navbar.style.borderTop = "1px solid #fff";

            timer = setInterval(function () {
                t+=10;
                navT+=10;

                //父级nav上限
                if (navT>=navMaxH){
                    navT = navMaxH;
                }

                // navbar上限
                if (t>=maxH){
                    t = maxH;
                    navT = navMaxH;
                    clearInterval(timer);
                }

                navbar.style.height = t + 'px';
                nav.style.height = navT + 'px';

            }, 10)
            //布尔值改为false,下次点击时,就会执行else中的语句
            bol = false;
        }else{
            
            navbar.style.borderTop = "0";
            
            timer = setInterval(function () {
                t-=10;
                navT-=10;

                //父级nav下限
                if (navT<=navMinH){
                    navT = navMinH;
                }
                
                //navbar下限
                if (t<=minH){
                    t = minH;
                    navT = navMinH;
                    clearInterval(timer);
                }

                navbar.style.height = t + 'px';
                nav.style.height = navT + 'px';

            }, 10)

            //布尔值改为true,下次点击时,就会执行if中的语句
            bol = true;
        }
    }
</script>
</html>
上一篇下一篇

猜你喜欢

热点阅读