背景
经常写Web页面的同学可能会碰到如下的诉求:
新增一个下拉框要求做的好看一点(鼠标放上去的颜色与原生Select不同,Select背景色也要有所变化)下拉框中的元素需要分组,分组以后最好还能有分割线以示区别下拉框的点击按钮要使用自定义的图标…
若是没有相关经验,拿到这种诉求可能头都要爆炸,不过当我们有过相关经验以后就会发现还真可以这么实现,而且自己做出来的Select既好玩又好看,自信心瞬间爆棚,下面小编在此分享一种实现方式:
实现步骤
自定义下拉框
<div class="col">
<button id="custSelect-btn">Click me!</button>
<div>
<div id="custSelect-bg" class="custSelect-bg" onclick="bgClick()"></div>
<ul id="custSelect-ul" class="custSelect-ul">
<li class="custSelect-li active" onclick="chooseLi()" value="Chinese">Chinese</li>
<li class="custSelect-li" onclick="chooseLi()" value="English">English</li>
<li class="custSelect-li" onclick="chooseLi()" value="French">French</li>
<li class="custSelect-li" onclick="chooseLi()" value="Japanese">Japanese</li>
</ul>
</div>
</div>
这里定义的Button用来点击展示我们的自定义Selectul#custSelect-ul 放在页面的最顶层,为我们的自定义Select,其布局方式为绝对布局,它所在的位置默认为其父级Div所在的位置,这样就省的我们再去通过JS来计算它的位置。div#custSelect-bg 放在自定义Select下面一层,用来点击关闭自定义Select,它占满了整个屏幕,但是是透明色的用户感知不到。具体样式见后面的代码块
效果图
未点击时
点击时
选择元素
原生Select
自定义与原生Select区别
相比于原生的Select我们有几点优势:
我们可以自定义下拉框的样式、描述、甚至图标我们可以为选项分组,更加适合在嵌套循环中生成下拉框,比如图中的场景,有两个类别Language,Subjects,类别下面分别有各自的元素自定义以后一切皆有可能,请大家自由发挥想象吧
代码
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Customized Select</title>
</head>
<style>
.row{
display: flex;
flex-direction: row;
padding: 5px;
border: 1px solid #000;
}
.col{
display: flex;
flex-direction: column;
padding: 5px;
margin-rigth: 5px;
border: 1px solid #000;
}
.custSelect-ul{
display: none;
position: absolute;
background-color: white;
border: 1px solid #999;
border-radius: 5px;
z-index: 9999;
margin: 0px;
padding: 0px;
}
.custSelect-ul .custSelect-li{
padding: 3px;
border: 1px solid #999;
list-style: none;
margin: 0px;
}
.custSelect-ul .custSelect-li:hover{
background-color: highlight;
}
.custSelect-ul .custSelect-li.active{
background-color: rgb(217, 196,114);
}
.custSelect-ul .custSelect-li-group{
background-color: #999;
}
.custSelect-bg{
display: none;
width: 100%;
height: 100%;
left: 0;
top: 0;
position: absolute;
}
</style>
<body>
<div class="row">
Customized Select
</div>
<div class="row">
<div class="col">
Padding Div
</div>
<div class="col">
<button id="custSelect-btn">Click me!</button>
<div>
<div id="custSelect-bg" class="custSelect-bg"></div>
<ul id="custSelect-ul" class="custSelect-ul">
<li class="custSelect-li custSelect-li-group">Language</li>
<li class="custSelect-li active" onclick="chooseLi()" value="Chinese">Chinese</li>
<li class="custSelect-li" onclick="chooseLi()" value="English">English</li>
<li class="custSelect-li" onclick="chooseLi()" value="French">French</li>
<li class="custSelect-li" onclick="chooseLi()" value="Japanese">Japanese</li>
<li class="custSelect-li custSelect-li-group">Subjects</li>
<li class="custSelect-li">Math</li>
<li class="custSelect-li">Physics</li>
</ul>
</div>
</div>
<div class="col">
<select>
<option>Chinese</option>
<option>English</option>
<option>French</option>
<option>Japanese</option>
</select>
</div>
</div>
</body>
<script type="text/javascript">
let btn = document.getElementById("custSelect-btn");
let ul = document.getElementById("custSelect-ul");
let bg = document.getElementById("custSelect-bg");
btn.onclick = function() {
ul.style.display = "block";
bg.style.display = "block";
}
bg.onclick = function() {
ul.style.display = "none";
bg.style.display = "none";
}
function chooseLi() {
let value = event.target.attributes["value"].nodeValue;
alert(`You have selected value: ${value}`);
}
</script>
</html>