使用 JavaScript 控制表格列依年份篩選顯示

前言

在許多資料表格中,我們常需要根據某個條件(例如年份)來篩選顯示特定的列。這段程式碼示範如何利用純 JavaScript 操作 DOM,根據下拉選單的選擇動態控制表格中帶有特定屬性(data-block)的列顯示與隱藏。適合需要簡潔且無依賴外部函式庫的前端工程師或自學者參考。

取得目標元素與資料列

首先,我們透過 document.getElementById 取得下拉選單元素,並使用 document.querySelectorAll 選取所有帶有 data-block 屬性的表格列(tr)。這些列代表不同年份的資料區塊。

const select = document.getElementById('select-download');
const blocks = Array.from(document.querySelectorAll('table tr[data-block]'));

儲存原始顯示狀態

為了避免直接覆寫 display 屬性導致無法還原,我們先讀取每個列的原始顯示狀態,並存入自訂的 data-orig-display 屬性中。這樣在切換篩選條件時,可以回復到原本的顯示方式。

blocks.forEach(el => {
  if (!el.dataset.origDisplay) {
    const d = window.getComputedStyle(el).display;
    el.dataset.origDisplay = (d && d !== 'none') ? d : 'block';
  }
});

篩選函式設計

applyFilter 函式會根據下拉選單的值,決定每個資料列是否顯示。若選擇 “all”,則全部顯示;否則只顯示 data-block 屬性值符合的列,其他則隱藏。

function applyFilter() {
  const val = select.value; // 例如 'all' 或 '2025'
  blocks.forEach(el => {
    const year = el.getAttribute('data-block');
    if (val === 'all' || year === val) {
      el.style.display = el.dataset.origDisplay;
    } else {
      el.style.display = 'none';
    }
  });
}

綁定事件與初始化

程式碼在 DOMContentLoaded 時執行,確保元素已存在。初次執行一次篩選,並監聽下拉選單的 change 事件,動態更新顯示狀態。

applyFilter();
select.addEventListener('change', applyFilter);

實務應用與延伸

這種用法適合靜態或小型資料表格的前端篩選,無需後端或複雜框架支援。若資料量大,可考慮分頁或虛擬滾動優化效能。未來也能擴充多條件篩選,或搭配 CSS 動畫增強使用者體驗。

常見問題與注意事項

  • 確保 data-block 屬性值與下拉選單選項一致。
  • 若原始顯示狀態非 block,此程式碼會自動保存並還原,避免顯示異常。
  • 若表格結構改變,需確認選取器仍正確。

完整程式碼

document.addEventListener('DOMContentLoaded', function () {
  const select = document.getElementById('select-download');
  if (!select) return;

  // 只控制 Greenshift 的區塊,且有 data-block(年份)
  const blocks = Array.from(
    document.querySelectorAll('table tr[data-block]')
  );

  // 記住原本的 display(以防原本不是 block)
  blocks.forEach(el => {
    if (!el.dataset.origDisplay) {
      const d = window.getComputedStyle(el).display;
      el.dataset.origDisplay = (d && d !== 'none') ? d : 'block';
    }
  });

  function applyFilter() {
    const val = select.value; // 'all' 或 '2025'...
    blocks.forEach(el => {
      const year = el.getAttribute('data-block');
      if (val === 'all' || year === val) {
        el.style.display = el.dataset.origDisplay;
      } else {
        el.style.display = 'none';
      }
    });
  }

  // 初次執行一次(依目前選中的值)
  applyFilter();

  // 監聽選單變更
  select.addEventListener('change', applyFilter);
});