owned this note
owned this note
Published
Linked with GitHub
---
title: Flex Panel Gallery
---
> 【目次】
> [TOC]
> Reference Website:
> 1. [重新認識 JavaScript: Day 15 隱藏在 "事件" 之中的秘密](https://ithelp.ithome.com.tw/articles/10192015)
> 2. [[筆記] JS30系列:監聽按鍵事件及撥放音效(Day1)](https://pjchender.blogspot.com/2017/01/js30day1.html)
> 3. [Wibibi 網頁設計教學百科](https://www.wibibi.com/)
> 4. [圖解:CSS Flex 屬性一點也不難](https://wcc723.github.io/css/2017/07/21/css-flex/)
> 5. [「JS30紀錄&心得」05 - Flex Panel Gallery](https://guahsu.io/2017/05/JavaScript30-05-Flex-Panel-Gallery/)
> 6. [HTML DOM - 選單開合範例](https://www.youtube.com/watch?v=SWhNYC6QYDc)
## **Flex Panel Gallery**
### **HTML**
```htmlmixed=
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Flex Panel Gallery</title>
</head>
<body>
<div class="panels">
<div class="panel panel1">
<p>Hey</p>
<p>Let's</p>
<p>Dance</p>
</div>
<div class="panel panel2">
<p>Give</p>
<p>Take</p>
<p>Receive</p>
</div>
<div class="panel panel3">
<p>Experience</p>
<p>It</p>
<p>Today</p>
</div>
<div class="panel panel4">
<p>Give</p>
<p>All</p>
<p>You can</p>
</div>
<div class="panel panel5">
<p>Life</p>
<p>In</p>
<p>Motion</p>
</div>
</div>
</body>
</html>
```
---
### **CSS**
```htmlmixed=
<link href='https://fonts.googleapis.com/css?family=Amatic+SC' rel='stylesheet' type='text/css'>
<style>
html {
box-sizing: border-box;
/*box-sizing用來調整區塊的內距與邊框
border-box包含內容寬度、內距與邊框寬度。
content-box設定的寬度僅為內容寬度,而內距與邊框額外加上去。
inherit繼承至父層的 broder-sizing 設定値。
*/
background: #ffc600;
font-family: 'helvetica neue';
font-size: 20px; /*字的大小*/
font-weight: 200;
}
body {
margin: 0; /*定義一個區域(例如DIV 或span)的外邊界距離,俗稱外距*/
}
*, *:before, *:after {
box-sizing: inherit;
}
.panels {
min-height: 100vh; /*最低高度值*/
overflow: hidden; /*元素超過某個範圍的時候該如何呈現 hidden自動隱藏超出的文字或圖片*/
display: flex; /*宣告*/
}
.panel {
background: #6B0F9C;
box-shadow: inset 0 0 0 5px rgba(255, 255, 255, 0.1); /* inset offset-x offset-y blur-radius spread-radius 陰影顏色; inset:用來設定內陰影*/
color: white;
text-align: center;
align-items: center;
/* Safari transitionend event.propertyName === flex */
/* Chrome + FF transitionend event.propertyName === flex-grow */
transition: font-size 0.7s cubic-bezier(0.61, -0.19, 0.7, -0.11), flex 0.7s cubic-bezier(0.61, -0.19, 0.7, -0.11), background 0.2s;
/* transition: property duration timing-function delay;
property用來定義可以產生 transition 屬性效果的屬性名稱,例如寬度、背景顏色 ...。
duration用來定義 transition 屬性發生的時間,單位為秒。
timing-function用來定義 transition 效果的發生速度。
delay用來定義多久之後開始發生 transition 效果。*/
font-size: 20px; /*字的大小*/
background-size: cover;
background-position: center;
flex: 1;
justify-content: center; /* 確定項目位於容器中心(可用於留白的語法)*/
display: flex;
flex-direction: column; /*改變軸線方向 column垂直從上往下排列*/
}
.panel1 {
background-image: url(https://source.unsplash.com/gYl-UtwNg_I/1500x1500);
}
.panel2 {
background-image: url(https://source.unsplash.com/1CD3fd8kHnE/1500x1500);
}
.panel3 {
background-image: url(https://images.unsplash.com/photo-1465188162913-8fb5709d6d57?ixlib=rb-0.3.5&q=80&fm=jpg&crop=faces&cs=tinysrgb&w=1500&h=1500&fit=crop&s=967e8a713a4e395260793fc8c802901d);
}
.panel4 {
background-image: url(https://source.unsplash.com/ITjiVXcwVng/1500x1500);
}
.panel5 {
background-image: url(https://source.unsplash.com/3MNzGlQM7qs/1500x1500);
}
/* Flex Items */
.panel>* {
margin: 0;
width: 100%;
transition: transform 0.5s; /*transition屬性實現簡單旋轉效果*/
flex: 1 0 auto;
/*flex-grow flex-shrink flex-basis
flex-grow: 元件的伸展性
flex-shrink: 元件的收縮性
flex-basis: 元件的基準值*/
display: flex;
justify-content: center; /* 確定項目位於容器中心(可用於留白的語法)*/
align-items: center; /*交錯軸的對齊設定*/
}
/* :first-child() & :last-child()
CSS的:偽類別,分別可以選取first(第一個)/last(最後一個)子元素*/
.panel>*:first-child {
transform: translateY(-100%); /*translateY(y) 定義 Y 軸方向的 2D 轉換*/
}
.panel.open-active>*:first-child {
transform: translateY(0);
}
.panel>*:last-child {
transform: translateY(100%);
}
.panel.open-active>*:last-child {
transform: translateY(0);
}
.panel p {
text-transform: uppercase; /*控制文章中的文字字母大小寫*/
font-family: 'Amatic SC', cursive;
text-shadow: 0 0 4px rgba(0, 0, 0, 0.72), 0 0 14px rgba(0, 0, 0, 0.45); /*X 軸方向的陰影 Y 軸方向的陰影 模糊範圍 陰影顏色*/
font-size: 2em;
}
.panel p:nth-child(2) {
font-size: 4em;
}
.panel.open {
flex: 5;
font-size: 40px;
}
</style>
```
---
### **JavaScript**
* .querySelector("class")
* 一種JS 的CSS 選擇器
* 如果找不到就會回傳null ,不然就回傳第一個符合的元素
* .querySelectorAll("class名稱")
* 取出所有符合class的元素
* .classList
* 可以管理標籤class的設定
* toggle
* 可以切換提供的class名稱
* propertyName
* 當發生transitionend事件時,propertyName屬性返回與轉換關聯的CSS屬性的名稱。
* includes
* 判斷陣列是否包含特定的元素
* forEach()
* 將陣列內的每個元素,皆傳入並執行給定的函式一次。
* .addEventListener()
* 監聽事件
* 第一個變數放 'click' 代表監聽滑鼠
* 第二個變數代表待這第一個變數發生的時候,要執行怎樣的事情
* transitionend
* 在CSS完成後觸發
```javascript=
<script>
let panels = document.querySelectorAll('.panel');
//宣告一個上次點擊的Panel,預設先給他panels
let lastClickPanel = document.querySelector('.panels');
function toggleOpen() {
//每次檢查進入的element與上次進入的element是不是相同
//若不相同,則把上次點擊的element移除open效果
//再把lastClickPanel指向為這次的elment
if (this !== lastClickPanel) {
lastClickPanel.classList.remove('open');
lastClickPanel = this;
}
this.classList.toggle('open');
}
// 參數 e 就是上面說的事件物件 (Event Object)
// 因為是參數,當然也可以自己定義名稱
function toggleActive(e) {
console.log(e.propertyName);
if (e.propertyName.includes('flex')) {
this.classList.toggle('open-active');
}
}
panels.forEach(panel => panel.addEventListener('click', toggleOpen));
panels.forEach(panel => panel.addEventListener('transitionend', toggleActive));
</script>
```