javascripthtmltumblr

How to toggle hashtags on blog posts individually by button on each blog post with same classname (vanilla js)


I have a div/button under each blog post-text to toggle the display of the tags/categories it is filled under. My understanding of JS is very limited. These two pieces of js is what I have but both gives the same result: clicking any of the toggle-buttons on any blog post only displays the first blog posts' tags. (this is on Tumblr btw)

//------ first option
var toggleTags = document.querySelectorAll(".toggle-tags");

for (var i = 0; i < toggleTags.length; i++) {
    toggleTags[i].addEventListener("click", showTags);
}
function showTags(e) {
    for (var i = 0; i < toggleTags.length; i++) {
        var activateTags = document.querySelector(".tags");
        activateTags.classList.toggle("tags-active");
    }
}

//------ or this one
const tagButtons = document.querySelectorAll(".toggle-tags");
for (const button of tagButtons) {
    button.addEventListener("click", function () {
        const activateTags = document.querySelector(".tags");
        activateTags.classList.toggle("tags-active");
    });
}

Given my lack of knowledge, I couldn't find an answer on here that I could apply myself, so I'm coming up short and I've absolutely no idea how to fix this myself. .tags is set to display:none; and .tags-active set to display:block!important;

This is the structure of each blog post in case that's of any use:

<article class="post">
    <div class="post-content text">
        post body
    </div>
    <div class="info">
        <div class="info-content">
            <div class="right">
                <div class="toggle-tags">toggle tags</div>
            </div>
        </div>
        <div class="tags">
            <a href="#">text</a>
            <a href="#">quotes</a>
        </div>
    </div>
</article>

Solution

  • The issue in your code is that const activateTags = document.querySelector(".tags"); will select the first element with the class .tags. So you are toggling the class only on that one. You need to iterate through them accordingly as you do with your buttons. Check the snippet.

    const tagButtons = document.querySelectorAll(".toggle-tags");
    const activateTags = document.querySelectorAll(".tags");
    tagButtons.forEach((button, index) => {
      button.addEventListener("click", () => {
        activateTags[index].classList.toggle("tags-active");
      });
    });
    .tags{
      display:none
    }
    
    .tags-active{
      display:block!important;
    } 
    <article class="post">
      <div class="post-content text">
        post 1
      </div>
      <div class="info">
        <div class="info-content">
          <div class="right">
            <div class="toggle-tags">toggle tags</div>
          </div>
        </div>
        <div class="tags">
          <a href="#">text</a>
          <a href="#">quotes</a>
        </div>
      </div>
    </article>
    <article class="post">
      <div class="post-content text">
        post 2
      </div>
      <div class="info">
        <div class="info-content">
          <div class="right">
            <div class="toggle-tags">toggle tags</div>
          </div>
        </div>
        <div class="tags">
          <a href="#">text</a>
          <a href="#">quotes</a>
        </div>
      </div>
    </article>
    <article class="post">
      <div class="post-content text">
        post 3
      </div>
      <div class="info">
        <div class="info-content">
          <div class="right">
            <div class="toggle-tags">toggle tags</div>
          </div>
        </div>
        <div class="tags">
          <a href="#">text</a>
          <a href="#">quotes</a>
        </div>
      </div>
    </article>

    I select all the activetags using querySelectorAll and choose the appropriate one to the clicked button using index.