Search code examples
javascripthtmlcss-selectorsevent-handlingdom-events

How to make every subsequent sibling after a button-wrapper disappear and restore their visibility again by pressing this very button?


I have 2 buttons on a page, "read more" and a "read less", which are created using a Page Builder in WP. I am trying to hide all elements after the Read More button when the page loads. Once the button is clicked I want the "Read More" to display: none; and then every element that was hidden after the "Read More" button to be visible and then that button be hidden while the "Read Less" button is then visible and vice versa.

So far I have this code which will display the parent and then all siblings excluding the element that I want as the starting point. I've watched a bunch of videos and I am sure there's an easier way to achieve this but it has to be done this certain way.

const readMore = document.getElementById("read-more");
const readLess = document.getElementById("read-less");

var getSiblings = function(elem) {

  // Setup siblings array and get the parent
  var siblings = [];
  var sibling = elem.parentNode.firstChild;

  // Loop through each sibling and push to the array
  while (sibling) {
    if (sibling.nodeType === 1 && sibling !== elem) {
      siblings.push(sibling);
    }
    sibling = sibling.nextSibling;
  }

  return siblings;
};
<body>
  <div>
    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quaerat, ex.
  </div>
  <div>
    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quaerat, ex.
  </div>
  <div class=".et_pb_button_0_wrapper">
    <button>
            <a href="#" target="_blank" id="read-more">READ MORE</a>
        </button>
  </div>
  <div>
    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quaerat, ex.
  </div>
  <div>
    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quaerat, ex.
  </div>
  <div>
    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quaerat, ex.
  </div>
  <div>
    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quaerat, ex.
  </div>
  <div>
    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quaerat, ex.
  </div>
  <div>
    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quaerat, ex.
  </div>

  <div>
    <button>
            <a href="#" target="_blank" id="read-less">READ LESS</a>
        </button>
  </div>
</body>


Solution

  • First, there is no need for a link placed inside a button.

    Second, one does not even have to give the <div/> wrapper around the "READ MORE" button a class-name.

    One can achieve what the OP is looking for with a minimum effort solution which does not involve any class-name but which ...

    The implementation then comes with a footprint as small as follows ...

    document
      .querySelector('#read-more')
      .addEventListener('click', ({ currentTarget: elmReadMore }) =>
    
        elmReadMore.disabled = true
      );
    
    document
      .querySelector('#read-less')
      .addEventListener('click', () =>
    
        document.querySelector('#read-more').disabled = false
      );
    div:has(#read-more:disabled),
    div:has(#read-more:not(:disabled)) ~ * {
      display: none;
    }
    button[id] {
      text-transform: uppercase;
      /* text-transform: capitalize; */
    }
    <div>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quaerat, ex.</div>
    <div>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quaerat, ex.</div>
    <!-- <div class="et_pb_button_0_wrapper"> -->
    <div>
      <button id="read-more">Read more</button>
    </div>
    <div>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quaerat, ex.</div>
    <div>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quaerat, ex.</div>
    <div>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quaerat, ex.</div>
    <div>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quaerat, ex.</div>
    <div>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quaerat, ex.</div>
    <div>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quaerat, ex.</div>
    <div>
      <button id="read-less">Read less</button>
    </div>