<!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> .box{200px;height:30px;line-height: 30px;margin: 20px auto;} .box span{display: block; 195px;line-height: 30px;border: solid 1px black;padding-left: 5px;} .box ul{ 200px; margin: 0;padding: 0;list-style: none;overflow: auto;border: solid 1px black;border-top:none;display: none;} .box ul li{padding-left: 5px;} .active{background: #35f;color: #fff;} </style> </head> <body> <div class="box"> <span>北京</span> <ul> <li class="active">北京</li> <li>上海</li> <li>广州</li> <li>深圳</li> <li>杭州</li> <li>西安</li> <li>安徽</li> </ul> </div> </body> <script> var ospan = document.querySelector(".box span"); var oul = document.querySelector(".box ul"); var ali = document.querySelectorAll(".box ul li"); var i = 0; //用i数值来设置ul的显示或隐藏,0为显示,1为隐藏 var index = 0; //设置默认索引值 ospan.innerHTML = ali[index].innerHTML; //把span标签的内容改为数组ali中索引为index的内容 setActive(); //调用函数setActi(在文末) // 绑定鼠标事件:: ospan.onclick=function(eve){ //绑定ospan点击事件 var e = eve || window.event; //处理事件源的兼容问题 e.stopPropagation(); // 阻止事件冒泡 if(i == 0){ oul.style.display = "block"; i=1; setActive(); //调用函数setActive(在文末) } //当i为0时,ul则显示,i设置为0 else{ oul.style.display = "none"; i=0; } //当i为1时,ul则隐藏,i设置为1 } document.onclick = function(){ oul.style.display = "none"; i=0; } //绑定页面的点击事件,点击页面时ul隐藏,i设置为1 for(var j=0;j<ali.length;j++){ //遍历数组 ali[j].index = j; //提前给li绑定索引,方便后面设置索引 ali[j].onmouseover = function(){ //绑定鼠标在li上移动事件 for(var k=0;k<ali.length;k++){ //遍历数组 ali[k].className = ""; // 取消所有li的className } this.className = "active"; //设置当前的li的className为"active",从而获得css中.active的样式 } ali[j].onclick = function(){ //绑定点击li的鼠标事件 ospan.innerHTML = this.innerHTML; //把span标签的内容改为当前li的内容 index = this.index; //把默认索引改为当前li的索引,从而使点击li后关闭下拉菜单,span标签内容变成当前点击选择的内容 } } // 绑定键盘事件:: document.onkeydown = function(eve){ e = eve || window.event; if(i == 0) return; //如果下拉菜单未打开(ul为隐藏状态),则不执行 if(e.keyCode == 38){ //在键盘上按上键 if(index == 0){ index = 0; } else{ index--; } //如果索引为0时,则索引一直为0(索引为0时,即此时li以及为第一个,所以不能再减了);否则索引自减1 setActive(); //调用函数setActi(在文末) ospan.innerHTML = ali[index].innerHTML; } if(e.keyCode == 40){ //按下键 if(index == ali.length-1){ index = ali.length-1; } else{ index++; } //如果索引为ali.length-1(数组最后一位)时,则索引一直为ali.length-1;否则索引自增1 setActive(); //调用函数setActi(在文末) ospan.innerHTML = ali[index].innerHTML; //把span标签的内容改为数组ali中索引为index的内容 } //按回车键,隐藏ul,设置i=0 if(keyCode == 13){ ospan.style.display = "none"; i = 0; } } //功能型函数:根据索引设置当前项 function setActive(){ for(var k=0;k<ali.length;k++){ //遍历数组 ali[k].className = ""; // 取消所有li的className } ali[index].className = "active"; //设置ali数组中索引为index的li的className为"active",从而获得css中.active的样式 } </script> </html>
实现了下拉菜单的所有功能,既可以鼠标操作也可以通过键盘实现上下选择,基本效果如下: