iT邦幫忙

2024 iThome 鐵人賽

DAY 26
0

利用flex的及transition呈現點擊效果

這段程式碼建立了一個具有互動效果的網頁,當你點擊每個面板時,面板會擴展並顯示隱藏的文字

完成圖:
https://ithelp.ithome.com.tw/upload/images/20241005/20168638d129Hjscc5.png

HTML
將這個頁面分成5大區,每個大區裡面再分別有3個小區

<!DOCTYPE html>
<html lang="zh-TW">
<head>
  <meta charset="UTF-8">
  <title>Flex Panels 💪</title>
  <link href='https://fonts.googleapis.com/css?family=Amatic+SC' rel='stylesheet' type='text/css'>
</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
html 和 body 設置了整體的樣式,包括背景顏色和字體。
.panels 使用 flex 佈局,使所有面板水平排列。
.panel 設置了背景顏色、陰影、字體顏色、對齊方式以及過渡效果。flex: 1 使面板平均分配空間,transition 設置了過渡效果。
panel1 到 panel5 設置了不同的背景圖片。
.panel > * 設置了面板內部元素的樣式和過渡效果。
.panel > *:first-child 和 .panel > *:last-child 設置了內部文字的初始位置,當面板打開時,它們會移動到中間。

html {
  box-sizing: border-box;
  background: #ffc600;
  font-family: 'helvetica neue';
  font-size: 20px;
  font-weight: 200;
}
body {
  margin: 0;
}
*, *:before, *:after {
  box-sizing: inherit;
}
.panels {
  min-height: 100vh;
  overflow: hidden;
  display: flex;
}
.panel {
  background: #6B0F9C;
  box-shadow: inset 0 0 0 5px rgba(255, 255, 255, 0.1);
  color: white;
  text-align: center;
  align-items: center;
  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;
  flex: 1;
  justify-content: center;
  align-items: center;
  display: flex;
  flex-direction: column;
}
.panel1 { background-image: url(https://source.unsplash.com/gYl-UtwNg_I/1500x1500); }
.panel2 { background-image: url(https://source.unsplash.com/rFKUFzjPYiQ/1500x1500); }
.panel3 { background-image: url(https://memeprod.sgp1.digitaloceanspaces.com/user-wtf/1591615571903.jpg); }
.panel4 { background-image: url(https://source.unsplash.com/ITjiVXcwVng/1500x1500); }
.panel5 { background-image: url(https://source.unsplash.com/3MNzGlQM7qs/1500x1500); }
.panel > * {
  margin: 0;
  width: 100%;
  transition: transform 0.5s;
  border: 1px solid red;
  flex: 1 0 auto;
  justify-content: center;
  align-items: center;
  display: flex;
}
.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 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;
}
.panel p:nth-child(2) {
  font-size: 4em;
}
.panel.open {
  font-size: 40px;
  flex: 5;
}

Javascript
選取所有具有panel class的元素。
定義一個函數toggleOpen,當面板被點擊時,切換open class,這會改變面板的大小。
定義一個函數toggleActive,當過渡效果結束且過渡的屬性名稱包含flex時,切換open-active class,這會改變面板內文本的顯示。
為每個面板添加點擊事件監聽器,當面板被點擊時,執行toggleOpen函數。
為每個面板添加過渡效果結束事件監聽器,當過渡效果結束時,執行toggleActive函數。

const panels = document.querySelectorAll('.panel'); // 選取所有面板

function toggleOpen(){
  this.classList.toggle('open'); // 切換 'open' class
}

function toggleActive(e){
  if (e.propertyName.includes('flex')){
    this.classList.toggle('open-active'); // 當過渡完成後切換 'open-active' class
  }
}

panels.forEach(panel => panel.addEventListener('click', toggleOpen)); // 當面板被點擊時調用 toggleOpen 函數
panels.forEach(panel => panel.addEventListener('transitionend', toggleActive)); // 當過渡效果結束時調用 toggleActive 函數


上一篇
# JavaScript實作DAY2
下一篇
# JavaScript實作DAY4
系列文
解鎖第一個人生成就清單:Javascript鐵人學習30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言