js+html+css模拟select 下拉框

以下代码实现了模拟下拉窗功能,鼠标与键盘都可以控制列表选项:  

 

 

 

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        .box{width: 300px;height: 40px;line-height: 40px;margin: 0 auto;text-indent: 4px;}
        .box span{display: block;width: 300px;height: 40px;border: solid 1px black;cursor: pointer;box-sizing: border-box}
        .box ul{margin: 0;padding: 0;list-style: none;border: solid 1px black;border-top:none;width: 300px;text-indent: 8px;display: none;;padding: 4px;box-sizing: border-box;}
        .box ul li.hover{background: #66f;color: #fff;}
    </style>
</head>
<body>
    <select name="" id="">
        <option value="北京">北京</option>
        <option value="上海">上海</option>
        <option value="广州">广州</option>
        <option value="深圳">深圳</option>
        <option value="杭州">杭州</option>
    </select>

    <div class="box">
        <span></span>
        <ul class="list">
            <li>北京</li>
            <li>上海</li>
            <li>广州</li>
            <li>深圳</li>
            <li>杭州</li>
        </ul>
    </div>
</body>
<script>
    var ospan = document.querySelector(".box span");
    var oul = document.querySelector(".list");
    var ali = oul.children;
    var flag=0;

    // 当前确认选中的索引
    var index = 0;

    // 键盘控制选项的索引
    var keyIndex;

    setDefault()
    for(var i=0;i<ali.length;i++){
        ali[i].xuhao = i;
        ali[i].onmouseover = function(){
            this.className = "hover";

            // 防止第一次鼠标进入选项,找不到keyIndex索引,而报错
            if(keyIndex !== undefined){
                ali[keyIndex].className = "";
            }
            
            // 鼠标进入选项时,将键盘的索引,设置为当前选项的索引
            keyIndex = this.xuhao;
            
            console.log(keyIndex);
        }
        ali[i].onmouseout = function(eve){
            var e = eve || window.event;
            stopBubble(e);

            this.className = "";
            // 鼠标离开选项时,将键盘的索引,设置为默认值
            // keyIndex = null;
        }
        ali[i].onclick = function(){
            ali[index].lastElementChild.remove();
            index = this.xuhao;
            setDefault()
            oul.style.display = "none";
            flag = 0;
        }
    }


    function setDefault(){
        ospan.innerHTML = ali[index].innerHTML;
        var em = document.createElement("em")
        em.innerHTML = "√";
        ali[index].appendChild(em);
    }

    ospan.onclick = function(eve){
        var e = eve || window.event;
        stopBubble(e);
        if(flag === 0){
            oul.style.display = "block";
            
            // 下拉菜单每次重新显示,都是需要将键盘所有内容设置为默认值
            if(keyIndex !== undefined){
                ali[keyIndex].className = "";
            }
            keyIndex = undefined;
            
            flag = 1;
        }else{
            oul.style.display = "none";
            flag = 0;
        }
    }


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


    function stopBubble(e){
        if(e.stopPropagation){
            e.stopPropagation()
        }else{
            e.cancelBubble = true;
        }
    }

    // ====================

    // 鼠标直接离开ul,将键盘的所有内容设置为默认值
    oul.onmouseout = function(){
        // console.log(keyIndex);
        if(keyIndex !== undefined){
            ali[keyIndex].className = "";
        }
        keyIndex = undefined;
    }
    

    document.onkeydown = function(eve){
        var e = eve || window.event;
        var code = e.keyCode || e.which;
        // 上
        if(code === 38){
            // 第一次按下键盘,需要将keyIndex设置为起点的上一个值
            if(keyIndex === undefined){
                keyIndex = ali.length;
            }
            // 计算索引
            if(keyIndex === 0){
                keyIndex = 0
            }else{
                keyIndex--;
            }
            // 如果索引为起点,不需要清除上一个元素的样式
            if(keyIndex !== ali.length-1){
                ali[keyIndex+1].className = "";
            }
            // 根据索引,添加样式
            ali[keyIndex].className = "hover";
        }
        // 下
        if(code === 40){
            if(keyIndex === undefined){
                keyIndex = -1;
            }
            if(keyIndex === ali.length-1){
                keyIndex = ali.length-1
            }else{
                keyIndex++;
            }
            if(keyIndex !== 0){
                ali[keyIndex-1].className = "";
            }
            ali[keyIndex].className = "hover"
        }
        // 回车
        if(code === 13){
            // 清除上一个选中的选项的选中状态
            ali[index].lastElementChild.remove();
            // 修改上一个选中的索引为键盘的索引
            index = keyIndex;
            // 设置选项的默认状态
            setDefault();
            // 隐藏下拉菜单
            oul.style.display = "none";
            // 修改下拉菜单显示状态
            flag = 0;
        }
    }






</script>
</html>

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值