前言
在許多資料表格中,我們常需要根據某個條件(例如年份)來篩選顯示特定的列。這段程式碼示範如何利用純 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);
});