iT邦幫忙

2024 iThome 鐵人賽

DAY 5
0
JavaScript

火箭通關JS30系列 第 5

JS30-05 - Flex Panel Gallery

  • 分享至 

  • xImage
  •  

課程目的:

image.png

image.png

這次的內容是如何利用CSS的flex屬性去控制展開頁面,達到點擊展開,字往內移動的效果
作品實做

本次功能實作重點:

  • 完善CSS
  • 偵測點擊執行動畫

完善CSS

 .panels {
        min-height: 100vh;
        overflow: hidden;
        display: flex;
      }
      .panel {
       flex: 1;
        display: flex;
        flex-direction: column;
        justify-content: center;
        background: #6b0f9c;
        box-shadow: inset 0 0 0 5px rgba(255, 255, 255, 0.1);
        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;
        font-size: 20px;
        background-size: cover;
        background-position: center;
      }
  1. panels是我們的最外層,內部包裹著五個panel ,先在panels 增加屬性display: flex;使元素轉為row的狀態,並且在panel 增加屬性flex: 1 ,每個子元素最大占比為1,這樣每個子元素可以占滿整個空間。
  2. 之後在panel增加 flex-direction: column; justify-content: center; 使內部字體垂直置中

image.png

.panel > * {
        margin: 0;
        width: 100%;
        transition: transform 0.5s;
        flex: 1 0 auto;
      }

.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);
        font-size: 2em;
        display: flex;
        justify-content: center;
        align-items: center;
      }

penel >* 內部增加flex: 1 0 auto,意思是該內部的元素會在有可用空間時擴展,但不會縮小,而且其初始大小是根據內容來決定的。

panel p 增加三個屬性display: flex; justify-content: center;  align-items: center;
使我們的字體可以垂直置中

.panel p:first-child {
        transform: translateY(-100%);
      }
 .panel p:last-child {
        transform: translateY(100%);
      }
 .panel.open {
        font-size: 40px;
        flex: 5;
      }
 .panel.open-active {
        p:first-child {
          transform: translateY(0);
        }
        p:last-child {
          transform: translateY(0);
        }    
  

最後我們選取p的第一個元素及最後一個元素設定transform: translateY(-100%);panel.open 是當我們之後要做點擊動作時要增加的class,因為要設定點擊後拉伸版面,增加屬性flex: 5

panel.open-active 則是panel.open 動畫結束後增加的class,在內部增加p:last-child跟p:first-child屬性transform: translateY(0)

偵測點擊執行動畫

 let panels = document.querySelectorAll(".panel");
     
      function fontBig() {
        //切換成有open屬性的class
        this.classList.toggle("open");
      }

      
      panels.forEach((panel) => {
        panel.addEventListener("click", fontBig);
        //在字放大動畫之後再執行
      });

panels首先先命名變數panels選取所有的panel

panels.forEach((panel) 監聽當panel被點擊之後執行函式fontBig

fontBig 在內部寫this.classList.toggle("open"),這樣當我們點擊其中一個panel元素時畫面將會拉身比例

偵測動畫執行完畢後執行字體內移

function fontMove(e) {
        //假設屬性的名字內含有flex
        if (e.propertyName.indexOf("flex") !== -1) {
          this.classList.toggle("open-active");
        }
      }
panels.forEach((panel) => {
        panel.addEventListener("click", fontBig);
        //在字放大動畫之後再執行
        panel.addEventListener("transitionend", fontMove);
      });

panels.forEach((panel) 在內部增加監聽器"transitionend" 代表監聽到動畫結束後執行fontMove

fontMove(e) 設定一個判斷式e.propertyName.indexOf("flex") !== -1,意思是:如果有監聽到動畫結束的屬性名稱為flex,則執行this.classList.toggle("open-active")(字體內移)

最後重點整理 :

  • 如果在同一個父層下可以利用first-child、last-child、nth-child()來設定子元素
  • classList.toggle可以做出開關的效果,若此class存在則移除,反之

導讀文件以及學習資源

JS30
[ Alex 宅幹嘛 ] 👨‍💻 深入淺出 Javascript30 快速導覽:Day 5:Flex Panel Gallery


上一篇
JS30-04 - Array Cardio Day 1
下一篇
JS30-06-Type Ahead
系列文
火箭通關JS3014
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言