效果
第一次看到這個效果是在阿里媽媽MUX的博客:UI動效—細微交互,極致體驗,裏面蒐集的一些微交互都讓人眼前一亮,恰好自己最近要做一個按鈕組,就參考了裏面Sergey Valiukh的一個設計。
源碼
和上兩篇博客一樣,相對簡單,爲了節省你的閱讀時間,直接上源碼:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>transition-tabs</title>
<link rel="stylesheet" href="transition-tabs.css">
</head>
<body>
<div class="transition-tabs">
<svg width="100%" height="100%">
<defs>
<mask id="mask">
<rect x="0" y="0" width="33.33%" height="100%" fill="white" />
</mask>
</defs>
<!-- 背景 -->
<rect x="0" y="0" width="100%" height="100%" fill="#5d5070"/>
<!-- 頂層遮罩 -->
<g mask="url(#mask)">
<rect x="0" y="0" width="33.33%" height="100%" fill="#75adcc"/>
<rect x="33.33%" y="0" width="33.33%" height="100%" fill="#f3b16d"/>
<rect x="66.66%" y="0" width="33.33%" height="100%" fill="#e55b56"/>
</g>
</svg>
<!-- 底層的文字,點擊文字切換動畫 -->
<div>
<span>前85%</span>
<span>85%~95%</span>
<span>後5%</span>
</div>
</div>
<script src="transition-tabs.js"></script>
</body>
</html>
.transition-tabs {
position: relative;
width: 300px;
height: 30px;
}
.transition-tabs div{
position: absolute;
width: 100%;
left: 0;
top: 0;
display: flex;
text-align: center;
}
.transition-tabs div span{
flex: 1;
color: white;
line-height: 30px;
cursor: pointer;
}
.transition-tabs #mask rect {
position: absolute;
transition: transform 0.4s ease-in-out 0.1s;
transform: translate3d(0,0,0);
}
;(function(){
var mask = document.querySelector("#mask rect");
var handleClick = function(e){
console.log("click",e);
};
//事件代理
document.querySelector(".transition-tabs div").addEventListener("click", function(e){
var target = e.target;
if (target.nodeName.toLowerCase() == "span") {
var end = target.offsetLeft;
mask.style.transform = "translateX(" + end + "px)";
if (handleClick) {
handleClick(e);
}
}
});
})();
爲了避免大家複製粘貼的麻煩,已將該項目上傳到github,隨意使用:
實現
①mask(遮罩)
之前沒接觸過的知識點只有一個,就是svg的mask,作用和css中的mask一樣,使用mask層來控制顯示哪一部分,區別在於svg mask顯示mask區域爲白色的部分,css mask顯示mask區域爲黑色的部分。
盜圖一張:
但是css中的mask兼容性可謂慘不忍睹:
於是使用了SVG mask。
②移動遮罩
移動遮罩就使用了css中簡單的translate3D()
,比較簡單,就不說了,在綁定點擊事件的時候用了事件代理的方法,讓父級捕獲並處理三個子級(這裏指span)的點擊事件,既避免全局事件代理可能帶來的性能問題,又減少事件綁定次數。
總結
一個比較簡單的東西好像沒有必要寫,當做每週的一個記錄好了。
昨天面試官問了一些移動端的事件,感覺自己瞭解得不多,還是要穩紮穩打,擴大知識面廣度同時確保深度。這周正好發燒,剛退燒,休息之餘打算看看zepto的源碼,向優秀的人看齊,你纔會更加優秀,加油。