首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

手機版側邊欄滑出效果:CSS Transform + JavaScript 觸控實作完整指南

     編輯:程式設計疑難解答

需求:點擊漢堡圖標 / 從左緣右滑 → 左側欄滑入;再次點擊 / 左滑 → 滑出。核心技術:**CSS Transform 動畫 + 觸控事件攔截**。

HTML 結構

<div id="app">
  <header class="topbar">
    <button id="menuBtn" aria-label="選單">☰</button>
    <h1>標題</h1>
  </header>
  <div id="sidebar" class="sidebar">
    <nav><ul><li>選項 1</li><li>選項 2</li></ul></nav>
  </div>
  <main id="content" class="content">頁面內容</main>
  <div id="overlay" class="overlay"></div>
</div>

CSS 關鍵樣式

/* 側邊欄預設隱藏在左側外部 */
.sidebar {
  position: fixed; top: 0; left: 0; bottom: 0; width: 260px;
  background: #fff; box-shadow: 2px 0 8px rgba(0,0,0,.15);
  transform: translateX(-100%); /* 關鍵:GPU 加速 */
  transition: transform 0.3s ease;
  z-index: 1000;
}
.sidebar.open { transform: translateX(0); }

/* 遮罩層 */
.overlay {
  position: fixed; inset: 0; background: rgba(0,0,0,.4);
  opacity: 0; visibility: hidden; transition: opacity 0.3s;
  z-index: 999;
}
.overlay.show { opacity: 1; visibility: visible; }

/* 內容區可選:側欄開啟時右移或縮放 */
.content { transition: transform 0.3s ease; }
.content.shifted { transform: translateX(260px); }

JavaScript 邏輯 (原生 ES6)

const sidebar = document.getElementById('sidebar');
const overlay = document.getElementById('overlay');
const menuBtn = document.getElementById('menuBtn');
const content = document.getElementById('content');

function openSidebar() {
  sidebar.classList.add('open');
  overlay.classList.add('show');
  content.classList.add('shifted');
  document.body.style.overflow = 'hidden'; // 防止背景滾動
}
function closeSidebar() {
  sidebar.classList.remove('open');
  overlay.classList.remove('show');
  content.classList.remove('shifted');
  document.body.style.overflow = '';
}
function toggleSidebar() {
  sidebar.classList.contains('open') ? closeSidebar() : openSidebar();
}

// 1. 點擊按鈕切換
menuBtn.addEventListener('click', toggleSidebar);

// 2. 點擊遮罩關閉
overlay.addEventListener('click', closeSidebar);

// 3. 觸控滑動手勢 (從左緣右滑開啟,左滑關閉)
let startX = 0;
const THRESHOLD = 80; // 觸發閾值 px

document.addEventListener('touchstart', e => {
  startX = e.touches[0].clientX;
}, { passive: true });

document.addEventListener('touchend', e => {
  const endX = e.changedTouches[0].clientX;
  const deltaX = endX - startX;
  if (startX < 30 && deltaX > THRESHOLD) { // 從左緣右滑
    openSidebar();
  } else if (deltaX < -THRESHOLD) { // 左滑關閉
    closeSidebar();
  }
}, { passive: true });

// 4. ESC 鍵關閉
document.addEventListener('keydown', e => { if (e.key === 'Escape') closeSidebar(); });

進階優化

  • 滑動跟隨手指: 在 touchmove 中即時設定 sidebar.style.transform = \`translateX(\${Math.min(0, -260 + deltaX)}px)\`,釋放時判斷閾值決定彈回或彈開 (需配合 transition: none 臨時關閉動畫)。
  • 無障礙: 加上 aria-expanded、role="dialog"、焦點陷阱。
  • React/Vue 封裝: 提取為 <Drawer /> 元件,透過 v-model / 受控屬性控制。

常見坑

現象原因解決
滑動卡頓未用 transform / 觸發重排只動 transform/opacity,加 will-change: transform
遮罩點擊不關閉z-index 層級錯誤overlay z-index 低於 sidebar,高於 content
Android 返回鍵不關閉未監聽 back 事件WebView 加上 onBackPressed 處理或 History API

此方案純 CSS 動畫、零依賴、效能極佳,適用於所有現代行動瀏覽器與 WebView。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved