老师,举例一个导航栏下拉有过渡效果的demo

老师,举例一个导航栏下拉有过渡效果的demo

当鼠标移入某个栏目时,二级栏目就会展示下拉,并且有下拉过渡效果,当鼠标完全移出时,二级栏目才收回隐藏,并且有收回过渡效果

正在回答

登陆购买课程后可参与讨论,去登陆

2回答

同学你好,可以参考如下demo:

<!DOCTYPE html">

<html lang="en">

<head>

    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

    <title></title>

    <style type="text/css">

        * {

            margin: 0;

            padding: 0;

            font-style: normal;

            font-family: 宋体;

        }

        body {

            text-align: center;

            font-size: 12px;

        }

        #content {

            margin: 0 auto;

            width: 600px;

        }

        #content #nav {

            height: 32px;

            margin-top: 60px;

            background-color: #464749;

        }

        #content #nav ul {

            list-style: none;

        }

        #content #nav ul li {

            float: left;

            width: 100px;

            line-height: 32px;

            position: relative;

        }

        #nav div {

            width: 100px;

            position: absolute;

            left: 0px;

            padding-bottom: 0px;

            float: left;

            height: 0;

            overflow: hidden;

            background-color: #23abf1;

        }

        #content #nav li .a {

            text-decoration: none;

            color: #FFFFFF;

            line-height: 32px;

            display: block;

            border-right-width: 1px;

            border-right-style: solid;

            border-right-color: #393A3C;

        }

        #nav div a {

            text-decoration: none;

            color: #FFFFFF;

            line-height: 26px;

            display: block;

        }

        #nav div a:hover {

            background-color: #0C7DBA;

        }

    </style>

</head>

<body>

    <div id="content">

        <div id="nav">

            <ul id="supnav">

                <li>

                    <a href="#" class="a">导航菜单</a>

                    <div>

                        <a href="#">导航菜单</a>

                        <a href="#">导航菜单</a>

                        <a href="#">导航菜单</a>

                    </div>

                </li>

                <li>

                    <a href="#" class="a">导航菜单</a>

                    <div>

                        <a href="#">导航菜单</a>

                        <a href="#">导航菜单</a>

                        <a href="#">导航菜单</a>

                        <a href="#">导航菜单</a>

                        <a href="#">导航菜单</a>

                    </div>

                </li>

            </ul>

        </div>

    </div>

    <script type="text/javascript">

        var supnav = document.getElementById("supnav");

        var nav = document.getElementById("nav");

        var btns = document.getElementsByTagName("li");

        var subnavs = nav.getElementsByTagName("div");

        var paddingbottom = 20;

        var defaultHeight = 0;

        function drop(obj, ivalue) {

            var a = obj.offsetHeight;

            var speed = (ivalue - obj.offsetHeight) / 8;

            a += Math.floor(speed);

            obj.style.height = a + "px";

        }

        window.onload = function () {

            for (var i = 0; i < btns.length; i++) {

                btns[i].index = i;

                btns[i].onmouseover = function () {

                    var osubnav = subnavs[this.index];

                    var sublinks = osubnav.getElementsByTagName("a");

                    if (osubnav.firstChild.tagName == undefined) {

                        var itarheight = parseInt(osubnav.childNodes[1].offsetHeight) * sublinks.length + paddingbottom;

                    } else {

                        var itarheight = parseInt(osubnav.firstChild.offsetHeight) * sublinks.length + paddingbottom;

                    }

                    clearInterval(this.itimer);

                    this.itimer = setInterval(function () {

                        drop(osubnav, itarheight);

                    }, 30);

                }

                btns[i].onmouseout = function () {

                    var osubnav = subnavs[this.index];

                    clearInterval(this.itimer);

                    this.itimer = setInterval(function () {

                        drop(osubnav, defaultHeight);

                    }, 30);

                }

            }

        }

    </script>

</body>

</html>

祝学习愉快~

  • leepulse 提问者 #1

    加上滑动门效果怎样添加?
    父级栏目下添加一条下滑线以表示高亮状态,在鼠标指向其他栏目时,该下划线以滑动门效果滑动到该栏目

    2021-10-29 20:07:48
  • leepulse 提问者 #2

     var paddingbottom = 20;

            // 默认高度为0

            var defaultHeight = 0;


            function drop(obj, ivalue) {

                var a = obj.offsetHeight;

                var speed = (ivalue - obj.offsetHeight) / 8;

                a += Math.floor(speed);

                obj.style.height = a + "px";

            }

    上面几句是什么意思?

    2021-10-30 09:32:24
  • leepulse 提问者 #3

     // 这里为什么要判断父级栏目对应的二级栏目列表的第一个子节点的标签名是否等于undefined?

    if (osubnav.firstChild.tagName == undefined) {

         var itarheight = parseInt(osubnav.childNodes[1].offsetHeight) * sublinks.length + paddingBottom;

    } else {

         var itarheight = parseInt(osubnav.firstChild.offsetHeight) * sublinks.length + paddingbottom;        }


    // 这里传入了两个参数osubnavitarheight,osubnav是父级栏目对应的二级栏目列表,itarheight分了两种情况,如果等于undefined,则计算二级栏目列表里的下标为1的子节点,如果不等于undefined,则计算二级栏目列表里的第一个子节点,这里osubnav.childNodes[1]和osubnav.firstChild表达的不都是div下第一个a标签吗?为什么要这样分开?

     this.itimer = setInterval(function () {

             drop(osubnav, itarheight);

    }, 30);


    2021-10-30 10:39:52
好帮手慕久久 2021-10-30 11:24:35

同学你好,解答如下:

1、滑动门说白了,就是来回移动一条下划线。只要在鼠标移入、移出事件中,更改下划线的位置,就可以了。例如:

https://img1.sycdn.imooc.com//climg/617cb574098ccccc07560196.jpg

https://img1.sycdn.imooc.com//climg/617cb5820954597106850507.jpg

https://img1.sycdn.imooc.com//climg/617cb5a90954b13209340349.jpg

https://img1.sycdn.imooc.com//climg/617cb5b50950274a07720224.jpg

2、paddingbottom 是为下拉菜单添加的padding-bottom样式,主要为了样式好看:

https://img1.sycdn.imooc.com//climg/617cb604095734b604740185.jpg

鼠标移出导航,下拉菜单的高度应该变成0;defaultHeight=0就是记录移出鼠标后下拉菜单的高度是0。

drop函数,是用来动态改变下拉菜单的高度的。它需要两个参数,第一个参数是“改变哪个元素的高度”,第二个参数是“该元素最终的高度是多少”,具体含义,请参考下图:

https://img1.sycdn.imooc.com//climg/617cb85609c371c811210362.jpg

3、如果项目打包上线时,有压缩操作,那么下拉列表中的空格,可能就会被删除(图一):

https://img1.sycdn.imooc.com//climg/617cb8e7091500d904960131.jpg

此时结构就会变成如下形式(图二):

https://img1.sycdn.imooc.com//climg/617cb9030946b1c914140100.jpg

图一、图二这两种结构,osubnav.firstChild.tagName的值是不同的。图一osubnav的firstChild是文本节点text(可以理解成是空格),它的tagName是undefined:

https://img1.sycdn.imooc.com//climg/617cb9d0093404af05360119.jpg

而图二的osubnav.firstChild.tagName才是a标签:

https://img1.sycdn.imooc.com//climg/617cb9d90978e91705090078.jpg

为了兼容这两种html结构,才做了如下处理:

https://img1.sycdn.imooc.com//climg/617cb9f5096fb8a107220133.jpg

itarheight就是计算得到的下拉列表的高度。

更多注释,请参考如下:

 var supnav = document.getElementById("supnav");

        var nav = document.getElementById("nav");

        var btns = document.getElementsByTagName("li");

        var subnavs = nav.getElementsByTagName("div");


        var paddingbottom = 20;

        var defaultHeight = 0;


        // 改变元素obj的高度,让其高度最终变成ivalue

        function drop(obj, ivalue) {  //定时器会每隔30ms,调用一次drop---》每30ms,改变元素的高度---》形成动画

            // 先获取obj当前的高度

            var a = obj.offsetHeight;

            // (ivalue - obj.offsetHeight)=目标高度-当前高度=还差多少高度要改变

            // (ivalue - obj.offsetHeight)再除以8,就是将需要变化的量分成8份--->改变的速度

            var speed = (ivalue - obj.offsetHeight) / 8;   //---》让高度改变,不是匀速的;这样效果好看

            // a=元素当前的高度 + 即将需要改变的量(speed)

            a += Math.floor(speed);

            // 把a的值,赋值给obj--->下一个30ms,让obj的高度变成a

            obj.style.height = a + "px";

        }




        // 获取下划线

        var line = document.getElementById("line")

        window.onload = function () {

            for (var i = 0; i < btns.length; i++) {

                btns[i].index = i;

                btns[i].onmouseover = function () {

                    // 移动下划线的位置

                    line.style.left = 100 * this.index


                    // subnavs是所有下拉列表,osubnav是当前的下拉列表#supnav下的div

                    var osubnav = subnavs[this.index];


                    // 获取当前下拉列表中的a标签(每一项内容)

                    var sublinks = osubnav.getElementsByTagName("a");


                    // 用if else语句,处理可能存在的兼容性问题

                    if (osubnav.firstChild.tagName == undefined) {

                        // itarheight是下拉列表的最终高度

                        //sublinks.length 是有几个a标签

                        //parseInt(osubnav.childNodes[1].offsetHeight)是获取a标签的高度

                        var itarheight = parseInt(osubnav.childNodes[1].offsetHeight) * sublinks.length + paddingbottom;

                    } else {

                        // itarheight是下拉列表的最终高度

                        var itarheight = parseInt(osubnav.firstChild.offsetHeight) * sublinks.length + paddingbottom;

                    }

                    // 防止开启多个定时器干扰结果,先将之前的定时器清掉

                    clearInterval(this.itimer);

                    this.itimer = setInterval(function () {

                        // 让下拉列表  高度 变成itarheight

                        drop(osubnav, itarheight);

                    }, 30);

                }

                btns[i].onmouseout = function () {

                    var osubnav = subnavs[this.index];

                    clearInterval(this.itimer);

                    this.itimer = setInterval(function () {

                        // 让下拉列表高度还原成0

                        drop(osubnav, defaultHeight);

                        // 下划线位置还原

                        line.style.left = 0

                    }, 30);

                }

            }

        }

祝学习愉快!


  • 提问者 leepulse #1

    但不是每个栏目下都有子栏目,我尝试过如果添加一个没有子栏目的父级栏目,控制台就会报错,这是什么原因

    2021-10-30 11:39:46
  • 好帮手慕久久 回复 提问者 leepulse #2
    同学你好,由于没有子栏目,导致如下代码无法获取元素,即osubnav.firstChild的值为null,而null没有tagName,所以会报错:

    https://img1.sycdn.imooc.com//climg/617cd79c09a5ae8a08330121.jpg

    老师只是给你写个例子,并没有处理类似于“没有子栏目”这样的情况;同学需要根据自己的需求、情况,独立处理一下下呦~



    2021-10-30 13:26:59
  • 提问者 leepulse 回复 好帮手慕久久 #3

    谢谢老师,明白了,我自己也根据需求,写出了导航下拉的功能,我觉得老师的例子是利用js动态计算子栏目列表的总高度,然后结合过渡效果实现导航下拉功能

    2021-10-30 13:59:06
问题已解决,确定采纳
还有疑问,暂不采纳

恭喜解决一个难题,获得1积分~

来为老师/同学的回答评分吧

0 星
请稍等 ...
意见反馈 帮助中心 APP下载
官方微信

在线咨询

领取优惠

免费试听

领取大纲

扫描二维码,添加
你的专属老师