js模拟select下拉菜单

<!DOCTYPE html>

<html lang="en">

<head>

  <meta charset="UTF-8">

  <meta name="viewport" content="width=device-width, initial-scale=1.0">

  <meta http-equiv="X-UA-Compatible" content="ie=edge">

  <title>Document</title>

  <style>

    *{

      padding: 0;

      margin: 0;

    }

    p{

      width: 300px;

      height: 30px;

      border: 1px solid #000;

      margin: 0 auto;

      margin-top: 30px;

      line-height: 30px;

      text-indent: 1em;

    }

    ul{

      width: 300px;

      border: 1px solid #000;

      border-top: 0;

      margin: 0 auto;

      display: none;

    }

    ul li{

      list-style: none;

      height: 30px;

      line-height: 30px;

      text-indent: 1em;

    }

    ul li.active{

      background: blue;

    }

  </style>

</head>

<body>

  <select name="" id="">

    <option value="1">1</option>

    <option value="2">2</option>

    <option value="3">3</option>

    <option value="4">4</option>

  </select>

  <p></p>

  <ul>

    <li class="active">列表1</li>

    <li>列表2</li>

    <li>列表3</li>

    <li>列表4</li>

    <li>列表5</li>

    <li>列表6</li>

  </ul>

</body>

  <script>

    //1.获取节点

    var pObj = document.querySelector("p");

    var ulObj = document.querySelector("ul");

    var liObj = ulObj.children;

    //设置pObj状态初始值

    var pObjStatus = 0;

    //设置鼠标滑过和键盘按下初始值

    var cssIndex = htmlIndex = 0;

    setActive(cssIndex);

    pObj.innerHTML = liObj[htmlIndex].innerHTML;

    //2.给pObj绑定onclick事件,第一次点击时ulObj出现,第二次点击时ulObj消失

    pObj.onclick = function(eve){

      var e = eve || window.event;

      //此时点击pObj会出现事件冒泡,向上传递,触发document的点击事件,所以要阻止事件冒泡

      if(e.stopPropagation){

          e.stopPropagation();

      }else{

          e.cancelBubble = true;

      }

      if(pObjStatus == 0){

        ulObj.style.display = "block";

        pObjStatus = 1;

      }else{

        ulObj.style.display = "none";

        pObjStatus = 0;

      }

    }

    //3.点击document时ulObj消失,pObj的状态回到初始值

    document.onclick = function(){

      ulObj.style.display = "none";

      pObjStatus = 0;

    }

    //4.遍历liObj,绑定事件

    for(var j = 0;j < liObj.length;j++){

        //提前存放liObj的索引

      liObj[j].index = j;

      liObj[j].onmouseover = function(){

        cssIndex = this.index;

        //把当前鼠标操作的对象的className设置为active,其他的设置为空

        for(var k = 0;k < liObj.length;k++){

          liObj[k].className = "";

        }

        this.className = "active";

      }

      liObj[j].onclick = function(){

          //liObj遍历的对象点击的时候把当前对象的值赋值给pObj

        pObj.innerHTML = this.innerHTML;

        //把当前对象的索引赋值给htmlIndex

        htmlIndex = this.index;

      }

    }

    //5.绑定键盘按下事件

    document.onkeydown = function(eve){

      var e = eve || window.event;

      var code = e.keyCode || e.which;

      //如果未出现下拉列表,则不执行键盘按下事件

      if(pObjStatus == 0) return;

      //判断键盘按下上键

      if(code == 38){

        htmlIndex = cssIndex;

        if(htmlIndex == 0){

          htmlIndex = 0;

          cssIndex = 0;

        }else{

          htmlIndex--;

          cssIndex--;

        }

        setActive(cssIndex);

        pObj.innerHTML = liObj[htmlIndex].innerHTML;

      }

      //判断键盘按下下键

      if(code == 40){

        htmlIndex = cssIndex;

        if(htmlIndex == liObj.length - 1){

          htmlIndex = liObj.length - 1;

          cssIndex = liObj.length - 1;

        }else{

          htmlIndex++;

          cssIndex++;

        }

        setActive(cssIndex);

        pObj.innerHTML = liObj[htmlIndex].innerHTML;

      }

      //判断键盘按下回车键

      if(code == 13){

        ulObj.style.display = "none";

        pObjStatus = 0;

      }

    }

    //根据索引设置当前项的样式

    function setActive(idx){

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

        liObj[i].className = "";

      }

      liObj[idx].className = "active";

    }

  </script>

</html>

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容