导航菜单优化制作

以前制作导航菜单,总要加许多id在HTML中,js代码也要将id挨个加上去,今日终于习得破解之法,不在用以前那种笨拙的方法了。

以下是HTML代码:

<body>
    <nav id="navlist">
        <ul>
            <li class="fucaidan xiaoshi">前端开发</li >
            <li class="fucaidan xiaoshi">后端开发</li >
            <li class="fucaidan xiaoshi">移动开发</li >
            <li class="fucaidan xiaoshi">数据库</li >
            <li class="fucaidan xiaoshi">大数据</li >
            <li class="fucaidan xiaoshi">运维&amp;测试</li >
            <li class="fucaidan xiaoshi">UI设计</li >
        </ul>
        <div class="zicaidan xiaoshi">
        <h3>基础1</h3>

        HTML/CSS JavaScript jQuery
        </div>
        <div class="zicaidan xiaoshi">
        <h3>基础2</h3>

        HTML/CSS JavaScript jQuery
        </div>
        <div class="zicaidan xiaoshi">
        <h3>基础3</h3>

        HTML/CSS JavaScript jQuery
        </div>
        <div class="zicaidan xiaoshi">
        <h3>基础4</h3>

        HTML/CSS JavaScript jQuery
        </div>
        <div class="zicaidan xiaoshi">
        <h3>基础5</h3>

        HTML/CSS JavaScript jQuery
        </div>
        <div class="zicaidan xiaoshi">
        <h3>基础6</h3>

        HTML/CSS JavaScript jQuery
        </div>
        <div class="zicaidan xiaoshi">
        <h3>基础7</h3>

        HTML/CSS JavaScript jQuery
        </div>
    </nav>

内容没有细做,以下是CSS代码:

<style>
    ul{
        list-style: none;
        box-sizing: border-box;
        padding: 15px 0;
        padding-left: 15px;
        border-radius: 10% 0 0 10%;
        color: white;
        background-color:#555;
        width: 150px;
        height: 320px;
    }
    ul li{
        padding: 10px 10px;
        cursor: pointer;
        background-color: #555;
    }
    div{
        box-shadow: 1px 0 2px #666;
        background-color: #999;
        color: white;
        height: 318px;
        width: 500px;
        position: absolute;
        left: 158px;
        top: 17px;
        padding-left: 20px;
        display: none;
        cursor: pointer;
    }
    </style>

js我使用了构造函数进行封装,这样可以有效的避免js中命名重复的问题,并且修改起来很方便,不需要在HTML中加入许多id,代码简洁了不少:

function navList(id){   
            var dad=document.getElementById(id);
            var fucaidan=dad.getElementsByClassName('fucaidan');
            var zicaidan=dad.getElementsByClassName('zicaidan');
            var xiaoshi=dad.getElementsByClassName('xiaoshi');
            var ul=dad.getElementsByTagName('ul');
        }
        new navList('navlist');

接下来将菜单的onmouse事件写入构造函数中就ok了,但在其中遇到了问题:

for(var i=0;i<fucaidan.length;i++){
        fucaidan[i].addEventListener('mouseenter',function(){
                zicaidan[i].style.display='block';
                this.style.backgroundColor='#999';
});

我们知道,for循环的便利在上面的函数中并不是我们所想的那样,而是一个定值。那么该如何解决这个问题呢?

event.target

event.target可以指出当前鼠标所指的元素,我们可以利用这一点写一个函数:

function findIndex(target,list){
                for(var i=0;i<list.length;i++){
                    if(target==list[i])    return i;
                }
                return -1;
            }

该函数的返回值便是与所指父菜单相同的索引值:

for(var i=0;i<fucaidan.length;i++){
                    fucaidan[i].addEventListener('mouseenter',function(event){
                        var a=findIndex(event.target,fucaidan);
                        zicaidan[a].style.display='block';
                        this.style.backgroundColor='#999';
                    });

这样问题就得到了完美解决。

最后再附上完整js代码:

<script>
        //利用构造函数进行封装,防止名字滥用,HTML动态添加
        function navList(id){   
            var dad=document.getElementById(id);
            var fucaidan=dad.getElementsByClassName('fucaidan');
            var zicaidan=dad.getElementsByClassName('zicaidan');
            var xiaoshi=dad.getElementsByClassName('xiaoshi');
            var ul=dad.getElementsByTagName('ul');
            //错误抛出,方便检查
            if(fucaidan.length!=zicaidan.length)     throw '父类菜单和子类菜单长度不匹配';
            //检索与父菜单索引相同子菜单
            function findIndex(target,list){
                for(var i=0;i<list.length;i++){
                    if(target==list[i])    return i;
                }
                return -1;
            }
            //子菜单和父菜单onmouse样式
            function appear(){    
                for(var i=0;i<fucaidan.length;i++){
                    fucaidan[i].addEventListener('mouseenter',function(event){
                        var a=findIndex(event.target,fucaidan);
                        zicaidan[a].style.display='block';
                        this.style.backgroundColor='#999';
                    });    
                    fucaidan[i].addEventListener('mouseleave',function(event){
                        var a=findIndex(event.target,fucaidan);
                        zicaidan[a].style.display='none';
                        this.style.backgroundColor='#555';
                        zicaidan[a].onmouseenter=function(){
                            zicaidan[a].style.display='block';
                            fucaidan[a].style.backgroundColor='#999';
                        }
                        zicaidan[a].onmouseleave=function(){
                            zicaidan[a].style.display='none';
                            fucaidan[a].style.backgroundColor='#555';
                        }
                    });
                }
            }
            appear();
        }
        new navList('navlist');
    </script>

不妨在上面的导航菜单中加入轮播效果:

<script>
        //利用构造函数进行封装,防止名字滥用,HTML动态添加
        function navList(id){   
            var N=1;
            var dad=document.getElementById(id);
            var fucaidan=dad.getElementsByClassName('fucaidan');
            var zicaidan=dad.getElementsByClassName('zicaidan');
            var xiaoshi=dad.getElementsByClassName('xiaoshi');
            var ul=dad.getElementsByTagName('ul');
            //错误抛出,方便检查
            if(fucaidan.length!=zicaidan.length)     throw '父类菜单和子类菜单长度不匹配';
            //设置菜单样式
            function addStyle(a){
                zicaidan[a].style.display='block';
                fucaidan[a].style.backgroundColor='#999';
            }
            //清除菜单样式
            function clearAll(){
                for(var i=0;i<fucaidan.length;i++){
                    zicaidan[i].style.display='none';
                    fucaidan[i].style.backgroundColor='#555';
                }
            }
            //检索与父菜单索引相同子菜单
            function findIndex(target,list){
                for(var i=0;i<list.length;i++){
                    if(target==list[i])    return i;
                }
                return -1;
            }
            //计时器
            function timeList(){
                clearAll();
                zicaidan[N].style.display='block';
                fucaidan[N].style.backgroundColor='#999';
                N++;
                if(N>fucaidan.length-1)    N=0;
            }
            //计时器开始
            var timeBegin=function(a){
                zicaidan[a].style.display='block';
                fucaidan[a].style.backgroundColor='#999';
                N=a;
                timing=setInterval(timeList,1000);
            }
            timeBegin(N-1);
            //计时器停止
            function timeEnd(){
                for(var i=0;i<fucaidan.length;i++){
                    fucaidan[i].onmouseenter=function(){
                        clearInterval(timing);
                        zicaidan[N-1].style.display='none';
                        fucaidan[N-1].style.backgroundColor='#555';
                    }
                    zicaidan[i].onmouseenter=function(){
                        clearInterval(timing);

                    }
                }
            }
            //子菜单和父菜单onmouse样式
            this.appear=function(){    
                for(var i=0;i<fucaidan.length;i++){
                    fucaidan[i].addEventListener('mouseenter',function(event){
                        var a=findIndex(event.target,fucaidan);
                        clearInterval(timing);
                        clearAll();
                        addStyle(a);
                    });
                    zicaidan[i].addEventListener('mouseenter',function(event){
                        var a=findIndex(event.target,fucaidan);
                        clearInterval(timing);
                        addStyle(a);
                    });
                    zicaidan[i].addEventListener('mouseleave',function(event){
                        var a=findIndex(event.target,zicaidan);
                        timeBegin(a);
                        addStyle(a);
                    });    
                    fucaidan[i].addEventListener('mouseleave',function(event){
                        var a=findIndex(event.target,fucaidan);
                        timeBegin(a);
                        addStyle(a);
                        zicaidan[a].onmouseenter=function(){
                            clearAll();
                            clearInterval(timing);
                            addStyle(a);
                        }
                    });
                }
            }
        }
        var navlist=new navList('navlist');
        navlist.appear();
    </script>

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏从零开始学自动化测试

python接口自动化2-发送post请求

前言 发送post的请求参考例子很简单,实际遇到的情况却是很复杂的,首先第一个post请求肯定是登录了,但登录是最难处理的。登录问题解决了,后面都简单了。 一...

2734
来自专栏后端之路

诡异的doctype

背景 我们在写html的时候可能不太注意doctype的书写 通常都会从原网页照抄一遍比如 <!DOCTYPE HTML PUBLIC "-//W3C//DT...

2917
来自专栏漏斗社区

一个能让你技能加身的HDWiki漏洞

1494
来自专栏Python小屋

Python爬虫基础:常用HTML标签和Javascript入门

大部分HTML标签是闭合的,由开始标签和结束标签构成,二者之间是要显示的内容,例如:<title>网页标题</title>。也有的HTML标签是没有结束标签的,...

581
来自专栏Android干货

Python浅谈requests三方库

632
来自专栏西安-晁州

关于vue.js中slot的理解

slot这块看官网文档,起初有点不懂,仔细研究还是最终理解了,slot是用来干嘛的呢,先看下一个例子:

802
来自专栏HTML5学堂

iframe基本知识及iframe版本Tab切换

HTML5学堂:本文当中,会依次为大家介绍iframe是什么,为何使用iframe;如何在当前网页中调用iframe中的标签和内容;如何在iframe中调用当前...

2854
来自专栏猿天地

nginx转发后后端怎么获取用户真实IP

经常有需求要获取访问用户的IP,在经过nginx转发后真实IP就被隐藏起来了,我们需要在头部信息里拿真实IP,下面是拿IP的代码,考虑了各种情况。 public...

3357
来自专栏西安-晁州

关于vue.js中slot的理解

1343
来自专栏闵开慧

struts2标签示例

常用UI标签: Textfield标签输出一个HTML单行文本输入控件 Textarea标签输出一个HTML多行文本输入控件 Radio标签输出单选按钮 che...

2756

扫码关注云+社区