想要制作这么一个效果还是比较麻烦的,但是代码并不难理解。首先,来看看 Html
代码。
<div class="container">
<div class="heading">
<h2>Custom Select</h2>
</div>
<div class="select">
<p>Please select</p>
<ul>
<li data-value="HTML5">HTML5</li>
<li data-value="CSS3">CSS3</li>
<li data-value="JavaScript">JavaScript</li>
<li data-value="JQuery">JQuery</li>
<li data-value="Backbone">Backbone</li>
</ul>
</div>
</div>
可见,我们并没有利用原生的 select
元素,而是利用其它元素来模拟这个效果。我们为 li
元素指定了 data-value
,主要是接下来我们会用 JQuery
获取选中值并将其放置到 p
元素下。
下面逐步来看 CSS
代码。
* {
margin: 0;
padding: 0;
}
html {
font-family: 'Terminal';
font-size: 62.5%;
}
body {
background-color: #33CC66;
}
- 将网页中所有元素的外边距和内边距设置为
0
。 - 将网页中的默认字体设置为
Terminal
,字体大小设置为62.5%
, 也就是10px
。 - 设置背景颜色为
#33CC66
。
<link href='http://fonts.googleapis.com/css?family=Lobster|Terminal+Dosis' rel='stylesheet' type='text/css'>
上面我们用到了 Terminal
字体,而且接下来我们还会使用 Lobster
字体,所以用这行代码添加引用。
.heading, .select {
display: block;
width: 22rem;
margin: 0 auto;
text-align: center;
}
.heading {
width: 28rem;
margin-top: 10rem;
margin-bottom: 2rem;
}
.heading h2 {
font-size: 6rem;
font-family: 'Lobster';
color: #ffffff;
}
- 指定
headng, select
宽度并指定其水平居中。 - 修改
heading
的宽度,主要是为了让其宽度大于select
的宽度,显得更加美观。然后指定其上外边距和下外边距。 - 设置
heading
下h2
元素的字体和字体大小,颜色。
.select > p, .select ul {
background-color: #ffffff;
font-size: 2rem;
border: 1px solid bisque;
border-radius: 5px;
margin-bottom: 0;
}
.select > p {
text-align: left;
padding: 1rem;
position: relative;
border-bottom-right-radius: 0;
border-bottom-left-radius: 0;
cursor: pointer;
color: rgba(102, 102, 102, .6);
}
.select > p:after {
display: block;
width: 10px;
height: 10px;
content: '';
position: absolute;
top: 1.4rem;
right: 2rem;
border-bottom: 1px solid #33CC66;
border-left: 1px solid #33CC66;
transform: rotate(-45deg);
transition: transform .3s ease-out, top .2s ease-out;
}
- 设置
p
和ul
元素的背景颜色和边框等设置。 - 为
p
元素单独指定样式,并设置其position
属性,主要是为了下面绘制右侧的下拉按钮。 - 利用
:after
在p
元素的右方绘制下拉按钮,可以看出来,我们是利用左下边框然后旋转-45
度 模拟的这个效果。值得注意的是,我们需要将其display
设置为block
,并且设置宽高,否则看不到 这个效果。
.select ul {
margin-top: 0;
border-top-left-radius: 0;
border-top-right-radius: 0;
list-style-type: none;
cursor: pointer;
overflow-y: auto;
max-height: 0;
transition: max-height .3s ease-out;
}
.select ul li {
padding-left: 0.5rem;
display: block;
line-height: 3rem;
text-align: left;
}
- 设置
ul
的一些默认属性,并将其设置最大宽度为0
,指定overflow-y
为auto
,这个时候ul
将会被隐藏。 - 在这里设置的时候我遇到了一个问题,就是
li
标签始终占不满ul
的一行,那是因为其默认有margin
和padding
,所以在一开始的时候就将网页中所有元素的外边距和内边距设置成了0
。
.select.open ul {
max-height: 20rem;
transform-origin: 50% 0;
-webkit-animation: slide-down .5s ease-in;
}
.select.open > p:after {
position: absolute;
top: 1.6rem;
transform: rotate(-225deg);
transition: transform .3s ease-in, top .2s ease-in;
}
- 为
open
设置最大高度,并为其指定动画效果。 - 将下拉按钮旋转
-225
度,并为其指定动画。
下面我们看看为 ul
元素指定的 slide-down
动画效果,这也是这个下拉特效的关键所在。
@-webkit-keyframes slide-down {
0% {
transform: scale(1, 0);
}
25% {
transform: scale(1, 1.25);
}
50% {
transform: scale(1, 0.75);
}
75% {
transform: scale(1, 1.1);
}
100% {
transform: scale(1, 1);
}
}
看到以上代码可能就都明白了,就是不断改变 ul
的大小,让其在 0.75-1.25
之间进行缩放,所以就会有那个跳动的效果了。
下面还有一些简单的 CSS
代码,不再解释。
.select ul li:hover {
background-color: rgba(102, 153, 102, 0.4);
}
.select .selected {
background-color: rgba(102, 153, 102, 0.8);
}
CSS
讲完了,下面就可以看看我们是如何利用 JQuery
控制这个效果的。
我们并不需要下载 JQuery
就可以使用,因为现在已经有很多网站提供了 CDN
服务,比如我使用的 BootCDN
。
<script src="http://cdn.bootcss.com/jquery/3.1.1/jquery.min.js"></script>
下面就可以使用 JQuery
了。
<script>
$(document).ready(function () {
$('.select ul li').on("click", function (e) {
var _this = $(this);
$('.select >p').text(_this.attr('data-value'));
$(_this).addClass('selected').siblings().removeClass('selected');
$('.select').toggleClass('open');
cancelBubble(e);
});
$('.select>p').on("click", function (e) {
$('.select').toggleClass('open');
cancelBubble(e);
});
$(document).on('click', function () {
$('.select').removeClass('open');
})
})
function cancelBubble(event) {
if (event.stopPropagation) {
event.preventDefault();
event.stopPropagation();
} else {
event.returnValue = false;
event.cancelBubble();
}
}
</script>
- 首先为
p
标签绑定click
事件,在触发的时候,为select
添加或移除open class
, 也就是将ul
显示出来。 - 为
li
绑定click
事件,当选中了一个li
元素的时候,首先获取到data-value
,然后将其赋值给p
标签,然后为选中的li
添加selected class
,与此同时利用siblings()
方法,让兄弟节点的selected class
移除。 - 为
document
设置click
事件,当我们点击网页中任何一处地方的时候,如果ul
是打开的,就将其关闭,不过这个时候由于所有元素都在document
内,所以我们需要阻止事件冒泡,调用自己写的cancelBubble()
方法。
好了,就讲到这里,有不理解的可在下方留言。