想要製作這麼一個效果還是比較麻煩的,但是代碼並不難理解。首先,來看看 Html 代碼。
<p class="container"> <p class="heading"> <h2>Custom Select</h2> </p> <p 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> </p></p>
可見,我們並沒有利用原生的 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() 方法。