iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 5
0
Modern Web

JavaScript 30實作心得筆記系列 第 5

Day5 Flex Panels Image Gallery

Day5 Flex Panels Image Gallery

Demo

使用Css的flex來製作動態收縮展開的畫面。

在畫面會有五張圖<div>垂直排列著,在點可以做到收縮展開的效果。

畫面有五個<div class="panel>使用flex:1進行排版

flex: flex-grow  flex-shrink  flex-basis ;

flex只有一個數值時,代表著是flex:flex-grow,其代表意義是5個panel會撐滿父元素。

原理是子元素有五個panel,每一個panelflex:flex-grow都為1,其加總為5,與原子元素未填滿的父元素panels的空間相除的解,與每個flex:flex-grow相乘就可以得到子元素panel增加的空間。flex:flex-grow的數值越大,佔父元素panels的的比列就越大。

panel中也把其子元素轉換成flex:flex-grow去撐滿父元素panel

panel中的子元素排列方向為由上而下的排列方式,水平位置置中。

display: flex;
justify-content: center; 
flex-direction: column;

接下來在panel建立兩個事件,第一個為click事件,當panel被點選時會觸發css

this.classList.toggle('open');
.panel.open {
    flex: 5;
    font-size:40px;
}

click事件是讓panel被點選時,判斷是否有.open的class,.toggle()有的話就移除,沒有就加入。

加入.openclass會讓panel變大,因為.open的class含有flex: 5;

第二件是panel轉場變大之後,觸發transitionend的事件。

原本在panel的子元素有三個,上下的子元素被transform: translateY向上向下位移100%。

transform: translateY(-100%)
transform: translateY(100%)

transitionend被觸發之後就把子元素拉回原本的位置,因此觸發.toggle(),加入或移除open-active的class

this.classList.toggle('open-active');

但這邊剛好發生一個問題,就是panel裡有兩個子元素同時間觸發,會連續.toggle()兩次結果沒變。

因此加入判斷式讓toggle()只觸發一次

if (e.propertyName.includes('flex')) {
    this.classList.toggle('open-active');
}

這樣就可以讓transitionend事件正常觸發。

Html:

<div class="panels">
    <div class="panel panel1">
        <p>Hey</p>
        <p>Let's</p>
        <p>Dance</p>
    </div>
    。
    。
    。
    <div class="panel panel5">
      <p>Life</p>
      <p>In</p>
      <p>Motion</p>
    </div>
</div>

Javascript:

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

panels加入兩個監聽動作,第一個是clicktransitionend,一個是點擊會有收縮展開的動作,另一個是收縮展開之後後續的動作。

this.classList.toggle('open');

Css:

flexbox

flex是display新的屬性,inline-flex亦屬於。使用flex會讓元素變成flex容器,而容器裡的元素會變成flex-item,而item可以被CSS的FlexibleBox的排版模組定。

  1. flex-direction
    flex-direction為items在容器中的主軸的排版方向,flex的主軸在設定display:flex的預設值為X軸。初始方向為平行從左至右。
flex-direction: row;
flex-direction: row-reverse;
/* 將flex-direction設定為column,就可把主軸(X)轉為Y軸做為主軸,item的排版方向為從上至下的垂直方向。 */
flex-direction: column;
flex-direction: column-reverse;
  1. justify-content
    justify-content是設定items在主軸(X)軸的空間中的位置。
justify-content: center;
justify-content: flex-start;
justify-content: flex-end; 
justify-content: space-between; 
justify-content: space-around;
  1. align-items
    align-items是說對應主軸的副軸,預設Y做為副軸。設定items在items在副軸的空間中的位置。
align-items: center;
align-items: start;
align-items: end;
align-items: stretch;
align-items: baseline; 
  1. align-self
    align-self與align-items的設定是相同的,但align-self用來覆寫align-items的的效果的。

範例

div:nth-child(3) {
  align-self: flex-end;
  background: pink;
}

  1. align-content

  2. flex
    The flex CSS property specifies how a flex item will grow or shrink so as to fit the space available in its flex container. This is a shorthand property that sets flex-grow, flex-shrink, and flex-basis.

/* Three values: flex-grow  flex-shrink  flex-basis */
flex: 2 2 10%;
  1. flex-grow
    flex-grow主要是指子元素會依照flex-grow數值的比列去撐滿父層空間。
    The flex-grow CSS property specifies the flex grow factor of a flex item. It specifies what amount of space inside the flex container the item should take up. The flex grow factor of a flex item is relative to the size of the other children in the flex-container.

  2. flex-shrink
    flex-shrink主要是指子元素比父層大時會依照flex-shrink數值的比列去縮減去符合父層空間。
    The flex-shrink CSS property specifies the flex shrink factor of a flex item. Flex items will shrink to fill the container according to the flex-shrink number, when the default width of flex items is wider than the flex container.

  3. flex-basis
    子元素的基本大小。
    The flex-basis CSS property specifies the initial main size of a flex item. This property determines the size of the content-box unless specified otherwise using box-sizing.
    [1]

tags: flex

上一篇
Day4 Array Cardio Day 1
下一篇
Day6 Ajax Type Ahead
系列文
JavaScript 30實作心得筆記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言