使用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样式还原相应样式,而且可以适当美化,做出更多样的下拉菜单。