網頁常需「展開/收縮」區塊 (FAQ、側邊欄、長文摘要)。純客戶端實現零 PostBack、體驗流暢。本文提供原生 JS + CSS 方案、jQuery 簡化版、無障礙 (ARIA) 加強版。
display: none/block 或 max-height: 0/auto (動畫)。localStorage 保持跨頁一致性。<button class="toggle-btn" data-target="#content1" aria-expanded="false">展開</button>
<div id="content1" class="collapsible" hidden>詳細內容...</div>
<script>
document.querySelectorAll('.toggle-btn').forEach(btn => {
btn.addEventListener('click', () => {
const target = document.querySelector(btn.dataset.target);
const isHidden = target.hidden;
target.hidden = !isHidden;
btn.textContent = isHidden ? '收縮' : '展開';
btn.setAttribute('aria-expanded', isHidden);
});
});
</script>
.collapsible {
overflow: hidden;
max-height: 0;
transition: max-height 0.3s ease-out;
}
.collapsible.expanded {
max-height: 500px; /* 足夠大的值 */
transition: max-height 0.5s ease-in;
}
// JS 切換 class
target.classList.toggle('expanded');
$('.toggle-btn').click(function() {
const $target = $($(this).data('target'));
$target.slideToggle(300);
$(this).text($target.is(':visible') ? '收縮' : '展開');
});
| 屬性 | 用途 |
|---|---|
aria-expanded="true/false" | 告知螢幕閱讀器展開狀態 |
aria-controls="targetId" | 關聯被控制元素 |
hidden (布林屬性) | 語義化隱藏,優於 display:none |
// 展開時存入
localStorage.setItem('collapsible_' + targetId, 'expapsed');
// 頁面載入還原
const saved = localStorage.getItem('collapsible_' + targetId);
if (saved === 'expanded') { target.hidden = false; btn.textContent = '收縮'; }
純前端實現輕量、無伺服器壓力、支援動畫與無障礙,是現代 Web 應用首選。