Is there a way to toggle content that's not in a wrapper element?

Imagine a blog article

<h2>sub</h2>
<p>paragraph</p>
<p>paragraph</p>
<p>paragraph</p>
<p>paragraph</p>
<h2>sub</h2>
<p>paragraph</p>
<p>paragraph</p>
<p>paragraph</p>
<p>paragraph</p>

I want to be able to click on H2 and hide/show the elements under it.

There is no way for me to manually add a wrapping div to those paragraphs.

So far I have tried a variation of this code

var article = document.getElementsByTagName("article")[0].getElementsByTagName("*");
var myElement = document.createElement("div");       
myElement.className="wrap";
for (var i = article.length - 1; i >= 0; i--) {
	if (article[i].tagName =="P") {
		myElement.appendChild(article[i])
	};

};
document.body.appendChild(myElement);

I know that that’s no where near solving the problem, but that’s where I keep circling

You can do something like this to walk the DOM to find siblings. It’s going to be flakey without a wrapper though, you need a clear marker in the DOM to stop at.

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title></title>
</head>
<body>
<h2>sub</h2>
<p>paragraph 1</p>
<p>paragraph 2</p>
<p>paragraph 3</p>
<p>paragraph 4</p>
<h2>sub 2</h2>
<p>paragraph 5</p>
<p>paragraph 6</p>
<p>paragraph 7</p>
<p>paragraph 8</p>
<script type="text/javascript">

var nextSiblingsOfType = function(current, nodeName, siblings) {
  siblings = siblings || []
  var next = current.nextElementSibling
  if (next && next.nodeName == nodeName) {
    siblings.push(next)
    return nextSiblingsOfType(next, nodeName, siblings)
  }
  return siblings;
}

document.body.addEventListener('click', function(event) {
  if (event.target.nodeName == 'H2') {
    var h2 = event.target;
    var siblings = nextSiblingsOfType(h2, 'P')
    siblings.forEach(function(sibling) {
      sibling.style.display = sibling.style.display == 'none' ? 'block' : 'none';
    })
  }
}, true)
</script>
</body>
</html>

If there’s an id or something on the next heading then you should be able to modify the code to check the nextSiblingsOfType function to look at the id rather than the nodeName.

1 Like

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.