skip to Main Content

I’m wondering based on the code below, how I can make a function the best way that I can use on my button to show content on for each element in the class one array if that makes sense? Now when I press it shows content for all the divs and I just want to show for the one in which my button belongs.

I’ve tried to make a class for buttons and loop through them as well, but I simply don’t understand how to do this.

function MyFunction(){
    
    let x = document.getElementsByClassName("one");

    for(i=0; i<x.length; i++){
        
        if (x[i].style.display === "block") {
            x[i].style.display = "none";
          } else {
            x[i].style.display = "block";
          }
    }
    
   
};
.one{
    display: none;
}
<h1>Testing</h1>
        <div class="one">
            <p>Some text</p>
        </div>
        <button onclick="MyFunction()">Show more!</button>
    </div>
    <div>
        <h1>Testing</h1>
        <div class="one">
            <p>Some other text</p>
        </div>
        <button onclick="MyFunction()">Show more!</button>
    </div>

2

Answers


  1. You could loop over all the buttons, attach an event listener to each one, and toggle the visibility of the element with the class 'one' in the parent of the button in the event handler.

    document.querySelectorAll('.open-btn').forEach(btn =>
      btn.addEventListener('click', e => {
        btn.parentElement.querySelector('.one').classList.toggle('hide');
      })
    );
    .hide {
      display: none;
    }
    <div>
      <h1>Testing</h1>
      <div class="one hide">
        <p>Some text</p>
      </div>
      <button class="open-btn">Show more!</button>
    </div>
    <div>
      <h1>Testing</h1>
      <div class="one hide">
        <p>Some other text</p>
      </div>
      <button class="open-btn">Show more!</button>
    </div>

    Alternatively, you can use event delegation and only attach the event listener to the closest static ancestor. (document is used here as an example, but you should choose a closer static ancestor.)

    document.addEventListener('click', e => {
      if (e.target.matches('.open-btn')) {
        e.target.parentElement.querySelector('.one').classList.toggle('hide');
      }
    });
    .hide {
      display: none;
    }
    <div>
      <h1>Testing</h1>
      <div class="one hide">
        <p>Some text</p>
      </div>
      <button class="open-btn">Show more!</button>
    </div>
    <div>
      <h1>Testing</h1>
      <div class="one hide">
        <p>Some other text</p>
      </div>
      <button class="open-btn">Show more!</button>
    </div>
    Login or Signup to reply.
    1. Wrap everything in an element¹ and register it to the "click" event. In the example below a <main> element is used. When <nain> is clicked, the event handler, toggleDiv is called.

      const main = document.querySelector("main");
      
      main.addEventListener("click", toggleDiv);
      
    2. The event handler, toggleDiv, is designed so that it delegates the "click" event to specific elements and ignores the rest. In the example below, only clicked <buttons> will react. See comments in the example for details.

    3. This programming paradigm is called event delegation wherein a single element² listens for a registered event when triggered on itself and/or any element within it. The type of element(s)³ that react to a registered event triggered directly on it can be broad (ex. div), specific (ex. #IdOfElement), or anything in between (ex. .classNameOfElements). The number of such elements is unlimited. Moreover, elements added dynamically at a later time are also included. That means eventListeners are not required for each element when created or existing when the page loads.

    ¹Element/Object can also be <body>, <html>, document, and window as well.

    ²event.currentTarget

    ³event.target

    Example

    const main = document.querySelector("main");
    
    main.addEventListener("click", toggleDiv);
    
    /**
     * Toggles the element placed before a clicked button.
     * @param {Object} event - Default Event Object. Uses event.target
     * property to determine exactly which element was clickrd by the user.
     */
    function toggleDiv(event) {
      // The element the user clicked.
      const clicked = event.target;
      // The element that sits before the clicked element.
      const div = clicked.previousElementSibling;
      // If the clicked element is a <button>...
      if (clicked.matches("button")) {
        // and if the element before the clicked element has display="block"...
        if (div.style.display === "block") {
          // assign it display="none"...
          div.style.display = "none";
          // otherwise...
        } else {
          // assign it display="block".
          div.style.display = "block";
        }
      }
    }
    .hidden {
      display: none;
    }
    <main>
      <h1>Testing</h1>
      <div>
        <div class="hidden">
          <p>Some text</p>
        </div>
        <button>Show more!</button>
      </div>
      <h1>Testing</h1>
      <div>
        <div class="hidden">
          <p>Some other text</p>
        </div>
        <button>Show more!</button>
      </div>
    </main>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search