iT邦幫忙

2024 iThome 鐵人賽

DAY 25
0
JavaScript

入門JavaScript系列 第 25

JavaScript與CSS(2)

  • 分享至 

  • xImage
  •  

JavaScript 和 CSS 的進階應用能夠實現更複雜的動態效果和交互,並提升網頁的性能與可維護性。進階應用涵蓋了動態樣式處理、複雜動畫、響應式設計的協同、深度整合 CSS 變數及預處理器等。這些技術可以讓開發者在打造用戶界面時具備更大的靈活性與控制力。

1. CSS 變數(Custom Properties)與 JavaScript 的動態樣式切換

CSS 變數能夠在整個應用中實現樣式的統一管理。透過 JavaScript 動態修改 CSS 變數,可以根據使用者行為或系統設定改變整個應用的外觀主題或特定樣式。

範例:實現深色模式與淺色模式切換

<style>
  :root {
    --bg-color: white;
    --text-color: black;
  }

  body {
    background-color: var(--bg-color);
    color: var(--text-color);
    transition: background-color 0.5s ease, color 0.5s ease;
  }
</style>

<button id="toggleTheme">Toggle Dark Mode</button>

<script>
  const root = document.documentElement;
  const toggleThemeButton = document.getElementById('toggleTheme');

  toggleThemeButton.addEventListener('click', function() {
    const currentBgColor = getComputedStyle(root).getPropertyValue('--bg-color').trim();
    
    if (currentBgColor === 'white') {
      root.style.setProperty('--bg-color', 'black');
      root.style.setProperty('--text-color', 'white');
    } else {
      root.style.setProperty('--bg-color', 'white');
      root.style.setProperty('--text-color', 'black');
    }
  });
</script>

此範例展示了如何使用 JavaScript 改變全局的 CSS 變數,從而在深色模式與淺色模式之間進行切換。

2. 複雜動畫與 JavaScript 控制的協同(CSS Animation + JavaScript)

利用 JavaScript 來控制複雜動畫的流程,配合 CSS @keyframes 動畫和 requestAnimationFrame(),我們可以實現對動畫的精細控制,如時間軸同步、動畫節奏控制等。

範例:使用 requestAnimationFrame() 與 CSS @keyframes 控制動畫進度

<style>
  .box {
    width: 100px;
    height: 100px;
    background-color: red;
    animation: move 5s linear paused;
  }

  @keyframes move {
    0% { transform: translateX(0); }
    100% { transform: translateX(500px); }
  }
</style>

<div class="box" id="box"></div>
<button id="start">Start</button>
<button id="pause">Pause</button>

<script>
  const box = document.getElementById('box');
  const startButton = document.getElementById('start');
  const pauseButton = document.getElementById('pause');

  let animationId;
  let startTime;

  function startAnimation() {
    startTime = Date.now();
    box.style.animationPlayState = 'running';
    animationId = requestAnimationFrame(step);
  }

  function pauseAnimation() {
    cancelAnimationFrame(animationId);
    box.style.animationPlayState = 'paused';
  }

  function step() {
    const currentTime = Date.now();
    const progress = (currentTime - startTime) / 5000;  // 5 秒動畫

    if (progress < 1) {
      animationId = requestAnimationFrame(step);
    }
  }

  startButton.addEventListener('click', startAnimation);
  pauseButton.addEventListener('click', pauseAnimation);
</script>

在這裡,我們通過 requestAnimationFrame() 結合 CSS 的 animation 屬性,實現了對動畫進度的控制,並且允許用戶暫停和重新啟動動畫。

3. 動態生成 CSS 規則與應用

除了操控內聯樣式或類別,JavaScript 可以動態創建樣式表並添加到文檔中,用於根據情境自動生成樣式。這對於大型應用程序中動態生成樣式或需要根據數據來更新樣式的場景非常有用。

範例:動態生成響應式樣式

<script>
  const styleSheet = document.createElement('style');
  document.head.appendChild(styleSheet);

  const screenWidth = window.innerWidth;

  if (screenWidth > 768) {
    styleSheet.sheet.insertRule('body { font-size: 18px; background-color: lightgreen; }', 0);
  } else {
    styleSheet.sheet.insertRule('body { font-size: 14px; background-color: lightcoral; }', 0);
  }

  window.addEventListener('resize', function() {
    const newScreenWidth = window.innerWidth;
    styleSheet.sheet.deleteRule(0);  // 刪除現有規則
    if (newScreenWidth > 768) {
      styleSheet.sheet.insertRule('body { font-size: 18px; background-color: lightgreen; }', 0);
    } else {
      styleSheet.sheet.insertRule('body { font-size: 14px; background-color: lightcoral; }', 0);
    }
  });
</script>

這段程式碼會根據窗口大小動態生成樣式,並在窗口大小改變時重新計算並更新樣式,達到響應式設計的效果。

4. 與 CSS Grid 和 Flexbox 的互動

CSS Grid 和 Flexbox 是現代網頁佈局的核心技術,JavaScript 可以動態改變其屬性來調整佈局,例如改變 Grid 的網格線數量或調整 Flexbox 方向。

範例:使用 JavaScript 改變 Flexbox 排列方向

<style>
  .flex-container {
    display: flex;
    flex-direction: row;
    justify-content: space-between;
    height: 200px;
    background-color: lightgrey;
  }

  .flex-item {
    width: 50px;
    height: 50px;
    background-color: teal;
    color: white;
    display: flex;
    justify-content: center;
    align-items: center;
  }
</style>

<div class="flex-container" id="flexContainer">
  <div class="flex-item">1</div>
  <div class="flex-item">2</div>
  <div class="flex-item">3</div>
</div>

<button id="toggleDirection">Toggle Direction</button>

<script>
  const flexContainer = document.getElementById('flexContainer');
  const toggleDirectionButton = document.getElementById('toggleDirection');

  toggleDirectionButton.addEventListener('click', function() {
    const currentDirection = getComputedStyle(flexContainer).flexDirection;
    flexContainer.style.flexDirection = currentDirection === 'row' ? 'column' : 'row';
  });
</script>

這個範例展示了如何動態改變 Flexbox 的排列方向,根據使用者行為改變佈局,從而實現更靈活的 UI 排版。

5. Scroll-Triggered 動畫與效果

滾動觸發動畫是現代網頁常見的交互形式之一,JavaScript 可以監控滾動事件並根據滾動位置來啟動或控制動畫效果,結合 CSS 進行更豐富的視覺表現。

範例:根據滾動位置改變元素樣式

<style>
  .box {
    width: 100px;
    height: 100px;
    background-color: red;
    margin-top: 2000px;  // 讓頁面有足夠的滾動距離
  }

  .sticky {
    position: sticky;
    top: 10px;
    background-color: blue;
  }
</style>

<div class="box" id="box">Scroll to see me change</div>

<script>
  const box = document.getElementById('box');

  window.addEventListener('scroll', function() {
    const boxTop = box.getBoundingClientRect().top;

    if (boxTop < window.innerHeight / 2) {
      box.classList.add('sticky');  // 添加 sticky 樣式
    } else {
      box.classList.remove('sticky');
    }
  });
</script>

在這個例子中,當用戶滾動到一定位置時,box 元素會自動變成一個 "sticky" 的固定定位,並改變其背景顏色。

6. 動態載入與替換樣式表

在大型應用中,根據不同的情境動態載入不同的樣式表可以提高性能,減少不必要的樣式計算和渲染。

範例:根據使用者選擇動態載入樣式表

<link id="themeStylesheet" rel="stylesheet" href="light-theme.css">
<button id="switchTheme">Switch Theme</button>

<script>
  const themeStylesheet = document.getElementById('themeStylesheet');
  const switchThemeButton = document.getElementById('switchTheme');

  switchThemeButton.addEventListener('click', function() {
    const currentTheme = themeStylesheet.getAttribute('href');
    themeStylesheet.setAttribute('href', currentTheme === 'light-theme.css' ? 'dark-theme.css' : 'light-theme.css');
  });
</script>

這段代碼根據用戶的選擇動態載入深色或淺色主題樣式表,適合用於主題切換或按需加載特定樣式。

總結

JavaScript 與 CSS 的進階應用可以實現更加靈活和動態的樣式控制,無論是使用 CSS 變數、控制複雜動畫、動態生成樣式,還是與 CSS 佈局系統交互,這些技術都能大大提升使用者體驗和頁面性能。隨著現代瀏覽器對這些技術的更好支持,這些進階應用成為了構建高效和互動性強的網頁應用不可或缺的部分。


上一篇
JavaScript與CSS(1)
下一篇
JavaScript與事件處理(1)
系列文
入門JavaScript30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言