使用js模拟下拉菜单-鼠标-键盘

使用js模拟下拉菜单

我们都知道HTML的原生下拉菜单的样式很单一,不美观,且有些样式难以修改,我们可以通过js模拟一个下拉菜单,这样就会比较方便操作它的样式了。
这里我们使用ul来模拟下拉框:

  <div class="box">
        <span>空当接龙</span>
        <ul>
            <li class="active">空当接龙</li>
            <li>红心大战</li>
            <li>蜘蛛纸牌</li>
            <li>远古纸牌</li>
            <li>金字塔纸牌</li>
            <li>纸牌</li>
            <li>...</li>
        </ul>
    </div>

给显示框设置点击事件:

   // 6.设置默认显示项的索引
    //设置默认css的索引和内容的索引
    var cssIndex = htmlIndex = 0;
    // 根据默认的索引,设置默认内容
    ospan.innerHTML = ali[htmlIndex].innerHTML;
    // 下拉菜单的当前项
    setActive(cssIndex);

    // 2.设置下拉菜单的显示或隐藏状态:0为显示,1为隐藏
    var i = 0;
    // 1.绑定显示框的点击事件
    ospan.onclick = function(eve){
        // 5.阻止事件冒泡
        eve.stopPropagation();
        // 3.根据状态显示或隐藏,同时别忘记修改状态
        if(i == 0){
            oul.style.display = "block";
            // 9.每次打开时根据最新索引,设置当前项
            setActive(htmlIndex)
            // K3-3.每次打开,需要将css索引设置为内容索引
            cssIndex = htmlIndex;
            i = 1;
        }else{
            oul.style.display = "none";
            i = 0;
        }
    }

点击空白隐藏,同时别忘记修改状态

   document.onclick = function(){
        oul.style.display = "none";
        i = 0;
    }

设置鼠标经过li时修改css样式以及li的点击事件

  for(var j=0;j<ali.length;j++){
        // 8.提前给li绑定索引,方便后面设置索引
        ali[j].index = j;
        
        // 7.鼠标经过li事件
        ali[j].onmouseover = function(){
            // K3-1.鼠标经过时,设置的是css索引
            cssIndex = this.index;
            // 取消所有,显示当前
            for(var k=0;k<ali.length;k++){
                ali[k].className = "";
            }
            // 注意:this就是鼠标经过的元素
            this.className = "active";
        }
        // 8.li的点击事件
        ali[j].onclick = function(){
            // 设置内容
            ospan.innerHTML = this.innerHTML;
            // K3-2.修改内容索引
            htmlIndex = this.index;
        }
    }

绑定键盘事件

 document.onkeydown = function(eve){
        // 如果下拉菜单没有显示,不执行
        if(i == 0) return;

        if(eve.keyCode == 38){
            // 按下上下键盘之前,先拿到鼠标最后停留的li的索引
            htmlIndex = cssIndex;
            // 修改内容和样式的索引
            if(htmlIndex == 0){
                htmlIndex = 0;
                cssIndex = 0;
            }else{
                htmlIndex--;
                cssIndex--;
            }
            // 修改li的当前项
            setActive(cssIndex)
            // 设置显示框的内容
            ospan.innerHTML = ali[htmlIndex].innerHTML;
        }
        if(eve.keyCode == 40){
            // 按下上下键盘之前,先拿到鼠标最后停留的li的索引
            htmlIndex = cssIndex;
            // 修改内容和样式的索引
            if(htmlIndex == ali.length-1){
                htmlIndex = ali.length-1;
                cssIndex = ali.length-1;
            }else{
                htmlIndex++;
                cssIndex++;
            }
            // 修改li的当前项
            setActive(cssIndex);
            // 设置显示框的内容
            ospan.innerHTML = ali[htmlIndex].innerHTML;
        }
        if(eve.keyCode == 13){
            // 回车隐藏下拉菜单,同时设置状态
            oul.style.display = "none";
            i = 0;
        }
    }

   

封装一个函数:根据索引设置当前项

    function setActive(idx){
        for(var k=0;k<ali.length;k++){
            ali[k].className = "";
        }
        ali[idx].className = "active";
    }

最终实现效果如下:
点击显示框,下拉菜单出现;
再次点击隐藏,或点击页面隐藏;
鼠标经过或使用上下键移动时改变背景色;
点击某一项或按下回车键时,菜单隐藏,显示框显示所点击选项内容;
使用上下键移动时,显示框内容也随之改变。
在这里插入图片描述
这样一个模拟下拉菜单就做好了,因为表单控件之外的元素没有onfocus属性,所以无法还原获得焦点的状态,当然也可以通过设置相应css样式还原相应样式,而且可以适当美化,做出更多样的下拉菜单。

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值