js模拟下拉菜单-鼠标、键盘事件操作

js模拟下拉菜单

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<style type="text/css">
			.box{width:200px;height:30px;line-height: 30px;margin: 20px auto;}
			.box span{display: block;width: 195px;line-height: 30px;
			 border: solid 1px black;padding-left: 5px;}
			.box ul{width: 200px; margin: 0;padding: 0;list-style: none;
			overflow: auto;border: solid 1px black;border-top:none;}
			.box ul li{padding-left: 5px;}
			.active{background: #35f;color: #fff;}
		</style>
	</head>
	<body>
	<div class="box">
        <span>北京</span>
        <ul style="display: none">
            <li class="active">北京</li>
            <li>上海</li>
            <li>广州</li>
            <li>深圳</li>
            <li>杭州</li>
            <li>西安</li>
            <li>安徽</li>
        </ul>
    </div>
	</body>
	
	<script type="text/javascript">
	   var ospan=document.querySelector(".box span");
	   var oul=document.querySelector(".box ul");
	   var ali=document.querySelectorAll(".box ul li");
	   //用i数值来设置ul的显示或隐藏,0为显示,1为隐藏
	   var i=0;
	   // var index=0;//设置默认索引值
	   var cssIndex=0;
	   var htmlIndex=0;//设置鼠标滑过和鼠标按下的初始值
	   //把span标签的内容改为数组ali中索引为index的内容
	   ospan.innerHTML=ali[htmlIndex].innerHTML;
	   setActive(cssIndex);//调用函数setActi(在文末)
	   
	   // 绑定鼠标事件::
	   ospan.onclick=function(eve){
		   //绑定ospan点击事件
		   var e= eve||window.event;
		   //处理事件源的兼容问题
		   e.cancelBubble = true;// 阻止事件冒泡
		   if(i==0){
			   oul.style.display="block";
			   i=1;//当i为1时,ul则隐藏,i设置为1
			   setActive(htmlIndex);//调用函数setActive(在文末)
		       cssIndex=htmlIndex;
		   }//当i为0时,ul则显示,i设置为0
		   else{
			    oul.style.display="none";
				i=0;
		   }
	   }//点击空白隐藏功能,同时修改状态
	   document.onclick=function(){
		   oul.style.display="none";
		   i=0;
	   }
	   //鼠标经过
	  for(var j=0;j<ali.length;j++){
		  //遍历数组
		  ali[j].index=j;
		  //提前给li绑定索引,方便后面设置索引
		  ali[j].onmouseover=function(){
			  cssIndex=this.index;
			  //绑定鼠标在li上移动事件
			  for(var k=0;k<ali.length;k++){
				  // 取消所有li的className
				  ali[k].className="";
			  }
			  //设置当前的li的className为"active",从而获得css中.active的样式
			  this.className="active";
		  }
		  ali[j].onclick=function(){
			  //绑定点击li的鼠标事件
			  ospan.innerHTML=this.innerHTML;
			  //把span标签的内容改为当前li的内容
			  htmlIndex=this.index;
			  //把默认索引改为当前li的索引,从而使点击li后关闭下拉菜单,span标签内容变成当前内容
		  }
	  }
	
	// 绑定键盘事件::
	document.onkeydown=function(eve){
		var e=eve||window.event;
		var code=e.keyCode||e.which;
		if(i==0) return;//当ul没有显示时,不能够生效键盘事件
		//如果下拉菜单未打开(ul为隐藏状态),则不执行
		if(e.keyCode==38){
			//在键盘上按上键
			htmlIndex=cssIndex;
			if(htmlIndex==0){
				htmlIndex=0;
				cssIndex=0;
			}else{
				//如果索引为0时,则索引一直为0(索引为0时,即此时li以及为第一个,所以不能再减了
				htmlIndex--;
				cssIndex--;
			}
			//如果索引为ali.length-1(数组最后一位)时,则索引一直为ali.length-1;否则索引自增1		
			setActive(htmlIndex);
			ospan.innerHTML=ali[cssIndex].innerHTML;
			//把span标签的内容改为数组ali中索引为index的内容
		}
		if(e.keyCode==40){
			//按下键
			htmlIndex=cssIndex;
			if(htmlIndex == ali.length-1){
				htmlIndex = ali.length-1;
				cssIndex = ali.length-1;
			}
			else{
				htmlIndex++;
				cssIndex++;
			}
			setActive(cssIndex);//修改li中的当前项;
			 ospan.innerHTML=ali[htmlIndex].innerHTML;
		}
		//按回车键,隐藏ul,设置i=0
		if(e.keyCode==13){
			// K8.回车隐藏下拉菜单,同时设置状态
			oul.style.display="none";
			i=0;
			//ospan.innerHTML=ali[index].innerHTML;
	}
	}
	
	//功能型函数:根据索引设置当前项
		function setActive(idx){
			for(var k=0;k<ali.length;k++){
				//遍历数组
				ali[k].className = "";
				// 取消所有li的className
			}
			ali[idx].className = "active";
			//设置ali数组中索引为index的li的className为"active",从而获得css中.active的样式
		}
	</script>
</html>
发布了22 篇原创文章 · 获赞 61 · 访问量 4028

猜你喜欢

转载自blog.csdn.net/zyfacd/article/details/104622129