第五天要學習的目標是熟悉 flex 的應用,以及認識 CSS 選擇器、偽類別、切換 class 用的 toggle
要做到切完版後,點擊不同的區塊會有放大及上下文字滑入的動畫
Github 檔案位置:05 - Flex Panel Gallery
網頁一開始的樣子如下
可以先去看看 最後的成品 如下
將程式的要求拆分步驟後,我們需要做的事情如下
在開始使用 Flex 前建議大家先破關 FLEXBOX FROGGY,裡面有 24 個 Flex 小遊戲
首先我們先幫主體的 .panels{}
加上 display: flex
讓顯示轉為橫向
幫 .panel{}
加上 flex: 1
利用 flex 的屬性自動等分填滿主體範圍
在 .panel{}
上利用 flex 屬性的 flex-direction
及 justify-content: center;
,讓文字置中對齊(使用前要先display: flex
)
.panel{
display: flex;
flex-direction: column;
justify-content: center;
}
最後,以 * 通用選擇器 為 .panel
中的所有元素加上以下屬性,一樣是等分填滿和垂直平行置中對齊
.panel > * {
flex: 1;
display: flex;
align-items: center;
justify-content: center;
}
這裡利用偽類別中的 :first-child 和 :last-child 單獨把上下兩段文字藏起來,以及寫好等等要做文字滑動特效的 class(此處選取的方式是 > 子代選擇器 和 .class 類別選擇器),
.panel > *:first-child{ transform: translateY(-100%); }
.panel.open-active > *:first-child{transform: translateY(0);}
.panel > *:last-child{ transform: translateY(100%); }
.panel.open-active > *:last-child{transform: translateY(0);}
並利用 flex 靈活排版的特性,做簡單的 item
CSS 放大動畫 class
.panel.open {
flex: 5;
font-size: 40px;
}
先利用前幾天學到的東西寫好 .panel
的 click
事件監聽
const panels = document.querySelectorAll('.panel');
function toggleOpen(){
console.log(this);
}
panels.forEach(panel => {
panel.addEventListener('click', toggleOpen);
});
這次比較不一樣的是,我們沒有使用 classList.add
和 classList.remove
兩個函式做 class
的添加和移除
而是用了 classList.toggle() 函式,他可以判斷 class 的有無而做開關,不需要拆分為 add 和 remove
function toggleOpen(){
console.log(this);
this.classList.toggle('open');
this.classList.toggle('open-active');
}
如果我們想要等 item
完整的放大完再讓兩行文字飄進來的話,可以再利用之前學到的 transitionend
事件
要特別注意的是 flex 屬性在 TransitionEvent 中的 propertyName,部分瀏覽器名稱是 "flex",部分是 "flex-grow",因此我們可以用昨天剛學到的 .includes('flex')
處理
function toggleActive(e){
console.log(e.propertyName);
if(e.propertyName.includes('flex')){
this.classList.toggle('open-active');
}
}
panels.forEach(panel => {
panel.addEventListener('transitionend', toggleActive);
})
.panels {
min-height: 100vh;
overflow: hidden;
display: flex;
}
.panel {
display: flex;
flex-direction: column;
justify-content: center;
flex: 1;
/* 省略... */
}
.panel > * {
/*margin: 0;
width: 100%;
transition: transform 0.5s; */
flex: 1;
display: flex;
align-items: center;
justify-content: center;
}
.panel > *:first-child{ transform: translateY(-100%); }
.panel.open-active > *:first-child{transform: translateY(0);}
.panel > *:last-child{ transform: translateY(100%); }
.panel.open-active > *:last-child{transform: translateY(0);}
.panel.open {
flex: 5;
font-size: 40px;
}
const panels = document.querySelectorAll('.panel');
function toggleOpen(){
console.log(this);
this.classList.toggle('open');
}
function toggleActive(e){
console.log(e);
if(e.propertyName.includes('flex')){
this.classList.toggle('open-active');
}
}
panels.forEach(panel => {
panel.addEventListener('click', toggleOpen);
});
panels.forEach(panel => {
panel.addEventListener('transitionend', toggleActive);
})
以上是第五天的製作紀錄,如有錯誤或不足的地方還請多多指教 >.<
Flexbox + JavaScript Image Gallery — #JavaScript30 5/30
[ Alex 宅幹嘛 ] 深入淺出 Javascript30 快速導覽:Day 5:Flex Panel Gallery
MDN Web Docs