Adaptive vanilla JS pagebrowser for dynamically generated content

Viewed 32

as a JS noob I'm stuck right now and would highly appreciate some help. My goal is to have a JS pagebrowser that works with content generated by my CMS (TYPO3). Content of different pages is rendered in divs with speaking ids; below you have links to these anchors plus a "show all" link. When you klick on a link to a "page" the respective page content div is shown and the others are hidden; if you click on "show all" all the page content divs are shown. However, if I click a page link after having clicked "show all" not all of the other page content divs are hidden as they should. I guess it has something to do with JS processing order but couldn't find out so far.

window.onload = function () {
    var pagelinks = document.querySelectorAll("a.subpage-toggle");

    for (var i = 0; i < pagelinks.length; i++) {
        pagelinks[i].onclick = function () {
            // Finding all elements of class 'active' (creates an array of results)
            let x = document.getElementsByClassName("active");
            // If class 'active' exists, remove it.
            if (x.length > 0) {
                x[0].classList.remove("active");
            }
            if ((this.href.split("#")[1]) !== "show-all") {
                // add class 'active' if ID matches href of link
                document.querySelector("#" + this.href.split("#")[1]).classList.add("active");
            } else {
                var subpagecontents = document.getElementsByClassName("subpage-content"),
                        len = subpagecontents !== null ? subpagecontents.length : 0,
                        j = 0;
                for (j; j < len; j++) {
                    subpagecontents[j].classList.add("active");
                }
            }
        };
    }
};
.subpage-toggle {
  display: block;
}

.subpage-content {
  display: none;
}

.subpage-content.active {
  display: block;
}
<div class="main">
<div id="name-of-page-one" class="subpage-content active">
<p>
Content Page 1
</p>
</div>
<div id="page-two-is-cool" class="subpage-content">
<p>
Content Page 2
</p>
</div>
<div id="nickname-of-page-three" class="subpage-content">
<p>
Content Page 3
</p>
</div>
<div class="pageoverview">
<ul>
<li><a class="subpage-toggle" href="#name-of-page-one">Name of page one</a></li>
<li><a class="subpage-toggle" href="#page-two-is-cool">Page two is cool</a></li>
<li><a class="subpage-toggle" href="#nickname-of-page-three">Nickname of page three</a></li>
</ul>
<a class="subpage-toggle" href="#show-all">Show all</a>
</div>
</div>

JSFiddle: https://jsfiddle.net/Jaydot/62cx5sh0/14/

1 Answers

You need to hide all the previous showing instead of just the first one:

Instead of

x[0].classList.remove("active");

do:

Array.from(x).forEach((element) => element.classList.remove("active"));

https://jsfiddle.net/nvg2aojb/

Related