iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 5
0
Modern Web

寫JS30天系列 第 5

JS 30 - 05 -Flex Panels Image Gallery

  • 分享至 

  • xImage
  •  

今天要製作一個點擊某區塊,該區塊的

  1. 大小會放大
  2. 隱藏內容顯示出來

首先先看看 css ,這裡的 css 很容易解析,就是一個 flex 容器包著另外一個 flex 容器,外層的是控制三行的排列,使用的 flex: 1 0 auto 表示三行等寬,在被添加 .open 時,會變成 flex: 3 0 auto; 。內層則是將上方的字 transform:translateY(-100%); 移到螢幕之上;下方的字 transform:translateY(100%);移到螢幕之下,在父層得到 .open-active 會回到原本應該在的位置。

.panels {
    overflow: hidden;
    display: flex;
}
.panel {
    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;
    flex: 1 0 auto;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
}
.panel>* {
    transition: transform 0.5s;
    flex: 1 0 auto;
    display: flex;
    justify-content: center;
    align-items: 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: 3 0 auto;
    font-size: 40px;
}

首先我們選到所有的區塊 .panel ,並監聽 click 事件,在被點擊時加入 .open.open-active
我們使用的是element.classList.troggle('.className')troggle() 是可以讓新增的className隨意的新增移除,這時候會發現,在區塊還沒完全打開時,字就已經跑出來了。這不是我們要的效果,我們希望「區塊完全打開後,字再跑出來」。

const panels = document.querySelectorAll('.panel');
function toggleOpen() {
    this.classList.toggle('open');
    this.classList.toggle('open-active');
}

panels.forEach(panel => panel.addEventListener('click', toggleOpen));

因此,我們可以對區塊監聽 transitionend 事件,並且將添加 .open-active 移到這裡再執行即可。
這時候會發現和預想的不一樣,字並沒有跑出來。 這時候 console.log(e.propertyName); 發現有 flex-growfont-size 兩個 transitionend 事件, toggle() 被執行了兩次,所以字又藏了回去。因此只要寫個判斷式讓觸法一次即可。

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('open-active');
    }
};

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

特別要注意的是google和firefox都是使用flex-grow,但是safari是使用flex,因此使用flex去篩選

程式碼
Demo


上一篇
JS 30 - 04 - Array Cardio Part I
下一篇
JS 30 - 06 - Ajax Type Ahead
系列文
寫JS30天30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言