Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> JavaScript

วิธีสร้าง Tab เปลี่ยนแท็บเมื่อ Hover ด้วย CSS และ JavaScript

สร้าง Tab Interface ที่เปลี่ยนเนื้อหาเมื่อ Hover (ชี้เมาส์) แทนการคลิก - เหมาะสำหรับเมนูดรอปดาวน์หรือ Quick Preview

โค้ดตัวอย่างสมบูรณ์

<!DOCTYPE html>
<html lang="th">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Tab Change on Hover</title>
  <style>
    * { box-sizing: border-box; }
    
    body {
      font-family: 'Segoe UI', Tahoma, sans-serif;
      padding: 24px;
      max-width: 900px;
      margin: 0 auto;
    }
    
    .tabs-container {
      display: flex;
      border: 1px solid #ccc;
      border-radius: 8px;
      overflow: hidden;
      background: #fafafa;
    }
    
    /* Tab Buttons Sidebar */
    .tab-sidebar {
      width: 25%;
      min-width: 180px;
      background: #f1f1f1;
      border-right: 1px solid #ccc;
    }
    
    .tab-btn {
      display: block;
      width: 100%;
      padding: 16px 20px;
      background: inherit;
      border: none;
      border-bottom: 1px solid #ccc;
      text-align: left;
      cursor: pointer;
      font-size: 16px;
      font-family: inherit;
      color: #333;
      transition: background-color 0.2s, color 0.2s;
    }
    
    .tab-btn:last-child {
      border-bottom: none;
    }
    
    .tab-btn:hover {
      background-color: #e0e0e0;
      color: #000;
    }
    
    .tab-btn.active {
      background-color: #ddd;
      color: #000;
      font-weight: 600;
    }
    
    /* Tab Content Area */
    .tab-content-area {
      flex: 1;
      padding: 24px;
      min-height: 250px;
    }
    
    .tab-panel {
      display: none;
      animation: fadeIn 0.2s ease;
    }
    
    .tab-panel.active {
      display: block;
    }
    
    @keyframes fadeIn {
      from { opacity: 0; transform: translateY(4px); }
      to { opacity: 1; transform: translateY(0); }
    }
    
    .tab-panel h3 {
      margin-top: 0;
      color: #333;
    }
  </style>
</head>
<body>
  <h2>แท็บเปลี่ยนเมื่อ Hover</h2>
  <p>ชี้เมาส์ที่แท็บด้านซ้ายเพื่อดูข้อมูลแผนกต่างๆ</p>
  
  <div class="tabs-container">
    <div class="tab-sidebar" role="tablist">
      <button class="tab-btn active" role="tab" aria-selected="true" aria-controls="panel-marketing" onmouseover="showTab('marketing', this)">การตลาด</button>
      <button class="tab-btn" role="tab" aria-selected="false" aria-controls="panel-operations" onmouseover="showTab('operations', this)">ปฏิบัติการ</button>
      <button class="tab-btn" role="tab" aria-selected="false" aria-controls="panel-finance" onmouseover="showTab('finance', this)">การเงิน</button>
      <button class="tab-btn" role="tab" aria-selected="false" aria-controls="panel-it" onmouseover="showTab('it', this)">เทคโนโลยีสารสนเทศ</button>
    </div>
    
    <div class="tab-content-area">
      <div id="panel-marketing" class="tab-panel active" role="tabpanel">
        <h3>แผนกการตลาด</h3>
        <p>รับผิดชอบการโปรโมท, บรานด์ดิ้ง, วิจัยตลาด, และการสร้างลูกค้าใหม่</p>
      </div>
      <div id="panel-operations" class="tab-panel" role="tabpanel">
        <h3>แผนกปฏิบัติการ</h3>
        <p>จัดการกระบวนการผลิต, logistics, supply chain, และคุณภาพสินค้า</p>
      </div>
      <div id="panel-finance" class="tab-panel" role="tabpanel">
        <h3>แผนกการเงิน</h3>
        <p>บัญชี, งบประมาณ, ภาษี, การเงินกองทุน, และรายงานทางการเงิน</p>
      </div>
      <div id="panel-it" class="tab-panel" role="tabpanel">
        <h3>แผนกไอที</h3>
        <p>พัฒนาระบบ, โครงสร้างพื้นฐาน, ความปลอดภัยข้อมูล, และนวัตกรรมดิจิทัล</p>
      </div>
    </div>
  </div>
  
  <script>
    function showTab(deptId, btnElement) {
      // ซ่อนทุก Panel
      document.querySelectorAll('.tab-panel').forEach(panel => {
        panel.classList.remove('active');
      });
      
      // ลบ Active Class จากทุกปุ่ม
      document.querySelectorAll('.tab-btn').forEach(btn => {
        btn.classList.remove('active');
        btn.setAttribute('aria-selected', 'false');
      });
      
      // แสดง Panel ที่เลือก
      const targetPanel = document.getElementById('panel-' + deptId);
      if (targetPanel) {
        targetPanel.classList.add('active');
      }
      
      // Active ปุ่มที่ Hover
      btnElement.classList.add('active');
      btnElement.setAttribute('aria-selected', 'true');
    }
    
    // Optional: Auto-show first tab on load
    document.addEventListener('DOMContentLoaded', () => {
      const firstBtn = document.querySelector('.tab-btn');
      if (firstBtn) {
        // Trigger hover effect หลังโหลดเสร็จ (Optional)
        // firstBtn.dispatchEvent(new Event('mouseover'));
      }
    });
  </script>
</body>
</html>

หลักการทำงาน

  1. HTML: Sidebar มีปุ่มแท็บ (role="tablist"), Content Area มี Panel (role="tabpanel")
  2. CSS: .tab-panel { display: none; } + .tab-panel.active { display: block; }
  3. JS: Event onmouseover เรียก showTab(id, btn) สลับ Class active
  4. Accessibility: ARIA attributes (role, aria-selected, aria-controls)

⚠️ ข้อควรพิจารณา (UX Considerations)

ประเด็นรายละเอียดแนวทางแก้
Accidental Activationเมาส์ผ่านๆ ก็เปลี่ยนแท็บเพิ่ม Debounce 100-200ms
Mobile/Touchไม่มี Hover บน Touch ScreenFallback: Click เพื่อเปิด, หรือใช้ Media Query
Keyboard NavTab/Enter ไม่ทำงานกับ Hoverเพิ่ม Keyboard Support (Focus = Show)
Screen Readersอาจสับสนจากการเปลี่ยนเร็วใช้ aria-live="polite" บน Panel

ปรับปรุง: Debounce + Keyboard Support

let hoverTimer = null;
const HOVER_DELAY = 150; // ms

function showTab(deptId, btnElement) {
  clearTimeout(hoverTimer);
  hoverTimer = setTimeout(() => {
    // ... switching logic ...
  }, HOVER_DELAY);
}

// Keyboard Support: Focus = Show Tab
document.querySelectorAll('.tab-btn').forEach(btn => {
  btn.addEventListener('focus', (e) => {
    const deptId = e.target.getAttribute('aria-controls')?.replace('panel-', '');
    if (deptId) showTab(deptId, e.target);
  });
});

// Touch Support: Click = Show (Mobile)
document.querySelectorAll('.tab-btn').forEach(btn => {
  btn.addEventListener('click', (e) => {
    if (window.matchMedia('(hover: none)').matches) {
      const deptId = e.target.getAttribute('aria-controls')?.replace('panel-', '');
      if (deptId) showTab(deptId, e.target);
    }
  });
});

กรณีใช้งานที่เหมาะสม

  • Mega Menu / Dropdown Navigation
  • Product Category Preview
  • Dashboard Sidebar Navigation
  • Documentation Sidebar
  • ไม่เหมาะ: Critical Actions, Forms, Mobile-first UI