---
# System prepended metadata

title: '[JS30] Day.5 Flex Panels Image Gallery'
tags: [JS30]

---

# [JS30] Day.5 Flex Panels Image Gallery 
###### tags: `JS30`
## 任務 Task
讓四張圖片被點擊時放大該圖片，並讓原本在外面的文字跑進來。

==完成時間：0.5hr==
## 步驟 Step
1. 先將文字及區塊置中，並將上下文字 `transfotm: translateY` 到外面。
2. 建立 `open` class 讓區塊的 `flex-glow` 及 `font-size` 變大。
3. 建立 `open-active` class 讓外面的文字 `translateY` 等於 `0`。
4. 監聽各個區塊的 `click event` 執行 `toggle('open')`。
5. 監聽各個區塊的 `transitionend` ，當區塊變大時，將`open-active` 加入 class。
## 筆記 Note
### CSS ">" 子代選取器
* 很常見的選取器！
* 用法為選曲子層的物件，所以不會影響到孫子層。

html：
```htmlmixed=
<div class = 'father'>
    <p>son</p>
    <div class = 'son'>
        <p>grandson</p>
        <div class = 'grandson'>
            <p>grandgrandson</p>
        </div>
    </div>
</div>

```
CSS

==result 1==
```css=
.father > p{
    color: red;
}
```


![](https://i.imgur.com/hmwtFZd.jpg)


==result 2==
```css=
.father p{
    color: red;
```


![](https://i.imgur.com/Zkg4XMk.jpg)


---

### JS transitionend event
* 每監聽到一個 `transitionend` 就跑一次 `callback function`。
* 所以當他執行 `toggleOpen` 時會監聽到兩次 `transitionend` 一個是 `font-size` 一個是 `flex-glow`。
* 如果直接在 `toggleAction` 裡加入 `this.classList.toggle('.open-active')` 就會因為監聽了兩次，而執行==兩次==，造成也 `toggle` 兩次，所以等於沒把 `.open-active` 加進去。
* 但如果今天在 `.open` 的 `class` 裡再新增一個條件，例如： `color: black` ，並且在 `transition:` 的地方加入 `color 0.5s` ，就會使在監聽 `transitionend` 的時候，執行==三次==的 `toogleAction` ，就能成功把 `.open-active` 加進 `class` 了。
* 所以才需要 `if` 去設定條件，當只監聽到 `transform = flex-grow` 或是 `transform = font-size` 時，才 `toggle` ，用意是只執行==一次==。


---
## 遇到問題 Problem
:::danger
⚠️ <font color=black>Problem</font>
:::
* 在使用 `callback function` 時，不小心用 `arrow function` 而無法使用 `this`。
:::info
:ok_hand: <font color=black>Revise</font>
:::
* 傳統函數每次呼叫，都會建立新的函數執行環境（Function Execution Context），以及建立新的 `this` 引用物件，指當下的呼叫者。
* `arrow function` 的 `this` 則指的是外層環境的 `this`，也就是說 `arrow funciton` 沒有他自己的 `this`。
## 想法 Idea
:::warning
:bulb: <font color=black>利用 `transitionend` 製作一個小動畫。
</font>
:::

### 方法 method
<iframe height="300" style="width: 100%;" scrolling="no" title="transitionend practice" src="https://codepen.io/jim876633/embed/bGLQWOd?default-tab=" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true">
  See the Pen <a href="https://codepen.io/jim876633/pen/bGLQWOd">
  transitionend practice</a> by Jim (<a href="https://codepen.io/jim876633">@jim876633</a>)
  on <a href="https://codepen.io">CodePen</a>.
</iframe>

* 不過做起來相當的麻煩，也會出現很多問題，而且相同屬性只能用一次，不適合用這個來做動畫 

## 連結
[transitionend event](https://developer.mozilla.org/en-US/docs/Web/API/Element/transitionend_event)