No Login Data Private Local Save

Native Accordion Group Generator - Online <details> Sync

7
0
0
0
Accordion Panels

Frequently Asked Questions

What is a native accordion?
A native accordion is built using HTML5 <details> and <summary> elements. It provides built‑in toggle behavior without any JavaScript framework. To achieve exclusive expand (true accordion behavior), a lightweight sync script is added.
Why use details/summary instead of JavaScript widgets?
They are semantic, SEO‑friendly, accessible by default, and work even if JavaScript is disabled. Browsers provide native keyboard navigation and screen‑reader support. With a tiny sync script you get the best of both worlds.
Is the generated code dependency‑free?
Yes. The generator produces pure HTML, optional CSS, and a short vanilla JavaScript snippet. No jQuery, Bootstrap, or external libraries are required. Just copy, paste, and it works.
Can I nest details elements inside each other?
Absolutely. The sync script only affects direct children of the container, so nested details behave independently. You can create complex nested accordions.
How does the sync script work?
We listen for the toggle event on the wrapper (capturing phase). When a <details> opens, the script closes all other direct‑child details that are currently open. This guarantees only one panel is expanded at a time when accordion mode is enabled.
Does it support multiple open panels?
Yes, simply disable “Accordion mode” in the generator. The generated code will then allow any number of details to be open simultaneously – behaving like plain details/summary without the sync script.
`; } else { js = '\n '; } return ` Native Accordion ${css}
${indent(htmlItems)}
${js} `; } function updateCode() { $codeBlock.text(generateFullCode()); } function updateAll() { updatePreview(); updateCode(); } // 初始化渲染 renderConfig(); updateAll(); // 为预览容器绑定手风琴同步 (捕获阶段) var previewContainer = document.getElementById('preview-accordion'); previewContainer.addEventListener('toggle', function(e) { if (!isAccordionMode) return; var details = e.target; if (details.parentNode === previewContainer && details.open) { previewContainer.querySelectorAll(':scope > details[open]').forEach(function(other) { if (other !== details) other.open = false; }); } }, true); // FAQ 容器绑定 (始终互斥) var faqContainer = document.getElementById('faq-accordion'); if (faqContainer) { faqContainer.addEventListener('toggle', function(e) { var details = e.target; if (details.parentNode === faqContainer && details.open) { faqContainer.querySelectorAll(':scope > details[open]').forEach(function(other) { if (other !== details) other.open = false; }); } }, true); } // 事件委托:配置面板输入 $panelList.on('input', '.item-title, .item-content', function() { var $item = $(this).closest('.panel-item'); var index = $item.data('index'); var title = $item.find('.item-title').val(); var content = $item.find('.item-content').val(); if (items[index]) { items[index].title = title; items[index].content = content; updateAll(); } }); // 事件委托:移动/删除按钮 $panelList.on('click', '.btn-move-up', function() { var index = $(this).closest('.panel-item').data('index'); if (index > 0) { var temp = items[index]; items[index] = items[index - 1]; items[index - 1] = temp; renderConfig(); updateAll(); } }); $panelList.on('click', '.btn-move-down', function() { var index = $(this).closest('.panel-item').data('index'); if (index < items.length - 1) { var temp = items[index]; items[index] = items[index + 1]; items[index + 1] = temp; renderConfig(); updateAll(); } }); $panelList.on('click', '.btn-delete', function() { var index = $(this).closest('.panel-item').data('index'); if (items.length > 1) { items.splice(index, 1); renderConfig(); updateAll(); } }); // 添加面板 $('#btn-add-panel').on('click', function() { items.push({ title: 'New Section', content: '' }); renderConfig(); updateAll(); // 滚动到新添加的项 $panelList.find('.panel-item').last().find('.item-title').focus(); }); // 开关变化 $toggleMode.on('change', function() { isAccordionMode = $(this).is(':checked'); // 如果开启互斥,立即关闭多余展开项 if (isAccordionMode) { var openList = previewContainer.querySelectorAll(':scope > details[open]'); if (openList.length > 1) { for (var i = 1; i < openList.length; i++) { openList[i].open = false; } } } updateCode(); }); $toggleStyling.on('change', function() { includeStyling = $(this).is(':checked'); updateAll(); }); // 复制代码 $('#copy-btn').on('click', function() { var code = $codeBlock.text(); navigator.clipboard.writeText(code).then(function() { var $btn = $('#copy-btn'); var originalHtml = $btn.html(); $btn.html('Copied!'); $btn.prop('disabled', true); setTimeout(function() { $btn.html(originalHtml); $btn.prop('disabled', false); }, 2000); }).catch(function() { alert('Copy failed. Please select the code manually.'); }); }); });