来自标记导出 html 的可折叠标题/手风琴



>我正在尝试实现一个网页,每个h2都充当手风琴的项目。单击时,标题下的内容应展开(隐藏后(。

我已经看过一堆教程,但它们通常使用特定的 html(使用链接或按钮(,但我的 html 是从标记语言(orgmode(导出的,因此无法以这种方式自定义(至少我不想(。我无法修改它们中的任何一个以满足我的需求。

我不确定最好的解决方案是使用 css 还是 javascript,或者两者兼而有之。这是 html 正文:

<div id="content">
<h1 class="title">Recipes</h1>
<div id="outline-container-org233deb6" class="outline-2">
<h2 id="org233deb6">Tea</h2>
<div class="outline-text-2" id="text-org233deb6">
</div>
<div id="outline-container-orgfbba0f7" class="outline-3">
<h3 id="orgfbba0f7">Ingredients</h3>
<div class="outline-text-3" id="text-orgfbba0f7">
<ul class="org-ul">
<li>1 tbsp tea leaves</li>
<li>1 cup water</li>
</ul>
</div>
</div>
<div id="outline-container-orgcc98fa7" class="outline-3">
<h3 id="orgcc98fa7">Instructions</h3>
<div class="outline-text-3" id="text-orgcc98fa7">
<ol class="org-ol">
<li>Boil some water</li>
<li>Put in tea leaves</li>
<li>Strain</li>
</ol>
</div>
</div>
</div>
</div>

据我所知,我试图在单击outline-2中的 h2 时隐藏/显示outline-3类。

由于您无法控制标记,因此您可以通过以下方式解决此问题:

const headerH2 = document.querySelectorAll('#content h2'); // first we put all wanted headers on variable
const outlinContent =  document.querySelectorAll("div[class^=outline]"); // you can use regex to catch all div begining with 'outline-'
outlinContent.forEach(function(item){  if (item.id !== 'outline-container-org233deb6') { item.classList.add('hide'); }  }); // hide  them, skipping the one contain the trigger
headerH2[0].addEventListener('click', function() { // adding click listener to the first (or the only one in this example
outlinContent.forEach(function(item){  if (item.id !== 'outline-container-org233deb6') {item.classList.toggle('hide'); } }); // toggle content display
});
.hide {display: none;}
<div id="content">
<h1 class="title">Recipes</h1>
<div id="outline-container-org233deb6" class="outline-2">
<h2 id="org233deb6">Tea</h2>
<div class="outline-text-2" id="text-org233deb6">CONTENT</div>
<div id="outline-container-orgfbba0f7" class="outline-3">
<h3 id="orgfbba0f7">Ingredients</h3>
<div class="outline-text-3" id="text-orgfbba0f7">
<ul class="org-ul">
<li>1 tbsp tea leaves</li>
<li>1 cup water</li>
</ul>
</div>
</div>
<div id="outline-container-orgcc98fa7" class="outline-3">
<h3 id="orgcc98fa7">Instructions</h3>
<div class="outline-text-3" id="text-orgcc98fa7">
<ol class="org-ol">
<li>Boil some water</li>
<li>Put in tea leaves</li>
<li>Strain</li>
</ol>
</div>
</div>
</div>
</div>

使内容可折叠:

注意:在此示例中,我使用h2作为触发器和同级div来保存内容。

const headerH2 = document.querySelectorAll('#content h2'); // first we put all wanted headers on variable
for (let i=0; i < headerH2.length; i++) { // you can use the modarn forEach, but this is much faster
let nextDiv = headerH2[i].nextElementSibling; // this is how you select the next element after the header
nextDiv.classList.add('hide'); // we hide all of them by default
headerH2[i].addEventListener('click', function() { // now we are adding click listener:
if (document.querySelector('#content div:not(.hide)')) {document.querySelector('#content div:not(.hide)').classList.add('hide')}; // this will close other open content divs if they exist
nextDiv.classList.remove('hide'); // this will show the right content when click
});
}
.hide {display: none;}
<div id="content">
<h2>TITLE 1</h2>
<div>CONTENT 1</div>
<h2>TITLE 2</h2>
<div>CONTENT 2</div>
<h2>TITLE 3</h2>
<div>CONTENT 3</div>
<h2>TITLE 4</h2>
<div>CONTENT 4</div>
<h2>TITLE 5</h2>
<div>CONTENT 5</div>
<h2>TITLE 6</h2>
<div>CONTENT 6</div>
</div>

作为旁注,html5 具有创建披露小部件的[details]元素,其中信息仅在小部件切换到"打开"状态时才可见,并且应该在此处使用以获取语义和 SEO 等......

一些有用的MDN链接,您可以在其中了解更多信息:

查询选择器全部

下一个元素兄弟

:非选择器

希望能解决您的问题并帮助其他人解决类似的问题。享受代码!

最新更新