Jing's 技術筆記

[JS30] Day 5: Flex Panels Image Gallery

2018/08/28 Share
用 CSS-Flex 與 JS 製作一個點擊後會展開的圖片展示效果

主要練習:

  • CSS - Flexbox
  • JS - transitionend event

CSS

Step 1 :

首先可以看到 HTML 中,有一個 .panels 包覆著 5 個 .panel,預覽畫面時,發現畫面是由上到下排列的,但我們要的是這 5 個 .panel 橫向並等寬的佔滿畫面,所以這時我們在 .panels 上使用 display: flex 屬性,讓內層子元素都變成 flex 屬性。

Step 2 :

這時會看到 .panel 變成橫向排列,但卻沒有占滿整個畫面,所以現在我們要在 .panel 上設置元素的比例,並讓擠在上方的文字置中顯示,所以加上 flex: 1justify-content: center

Step 3 :

接下來要讓文字垂直排列並平均分配在 .panel 中,所以再加上 display: flexflex-direction: column

Step 4 :

.panel 中最上面及最下面 p 元素裡的文字做位移效果,讓他在可視範圍外,並再加上一個 .active 的 class 以利等等搭配 JS 讓元素移回可視範圍內。
接著也在 .panel.open 中加上 flex: 5 使其觸發時會有展開的動畫。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
.panel > p:first-child{
transform:translateY(-100%);
}
.panel.active > p:first-child{
transform:translateY(0);
}
.panel > p:last-child{
transform:translateY(100%);
}
.panel.active > p:last-child{
transform:translateY(0);
}
.panel.open {
flex:5;
}


JS

Step 1 :

先抓取到 .panel 所有節點,接著設計一個可以透過新增/移除 class 方法來製作互動效果的 function 。

1
2
3
4
5
6
7
8
9
const panels = document.querySelectorAll('.panel');
function toggleOpen () {
this.classList.toggle('open')
}
function toggleActive(e) {
if (e.propertyName.includes('flex')) {
this.classList.toggle('active');
}
}

e.propertyName可以抓到觸發transitionend的屬性名稱,
.open 中觸發的 transition 屬性有兩個,分別為 fontflex
要使其在 flex 之後在觸發的話,就要判斷進來的是不是 flex
但因為 transition: flex 0.7s.. 這段在 sarafi 是 flex ,而其他瀏覽器為 flex-grow
所以不能用 e.property === 'flex' 來寫,會使其中一方瀏覽器抓不到值,
作者提到因為兩者都有 flex 的字眼,所以利用 .includes('flex') 來判斷, 只要 e.property 有包含到 flex 的字串就使其通過判斷,加入動畫效果。

Step 2 :

加上監聽事件,觸發上方的 function 。

1
2
panels.forEach(panel => panel.addEventListener('click', toggleOpen))
panels.forEach(panel => panel.addEventListener('transitionend', toggleActive));

完整 JS

1
2
3
4
5
6
7
8
9
10
11
12
const panels = document.querySelectorAll('.panel');
function toggleOpen () {
this.classList.toggle('open')
}
function toggleActive(e) {
// console.log(e.propertyName);
if (e.propertyName.includes('flex')) {
this.classList.toggle('active');
}
}
panels.forEach(panel => panel.addEventListener('click', toggleOpen))
panels.forEach(panel => panel.addEventListener('transitionend', toggleActive));

相關連結

CATALOG
  1. 1. Day 5: Flex Panels Image Gallery
  2. 2. CSS
    1. 2.1. Step 1 :
    2. 2.2. Step 2 :
    3. 2.3. Step 3 :
    4. 2.4. Step 4 :
  3. 3. JS
    1. 3.1. Step 1 :
    2. 3.2. Step 2 :
  4. 4. 完整 JS
  5. 5. 相關連結