可折叠 headings/accordion 来自导出的标记 html

Collapsible headings/accordion from markup exported html

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

我看过很多教程,但他们通常使用特定的 html(使用链接或按钮),但我的 html 是从标记语言 (orgmode) 导出的,所以可以'不会以这种方式定制(至少我不希望这样)。我无法修改其中任何一个以满足我的需要。

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

  <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>

据我所知,我正在尝试 hide/show outline-3 class 单击 outline-2 中的 h2。

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

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] element 创建一个披露小部件,其中的信息仅在小部件切换到 "open" 时可见状态,应该在这里使用以获得语义和 SEO 等...

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

querySelectorAll

nextElementSibling

:not selector

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