skip to Main Content

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>

2

Answers


  1. A sprinkling of CSS here, alongside your JS, will do wonders:

    .read-more.activated,
    .read-more:not(.activated) ~ :is(p, button) {
      display: none;
    }
    

    This snippet declares that:

    • when the .read-more button has the .activated class it will not display
    • when the .read-more button does not have the .activated class, all <p> or <button> elements which follow it (as subsequent siblings) will not display

    Then, all your JavaScript needs to deliver is:

    1. when the .read-more button is clicked, the .activated class is added to the .read-more button; and
    2. when the .read-less button is clicked, the .activated class is removed from the .read-more button.

    Working Example:

    const readMoreButton = document.querySelector('.read-more');
    const readLessButton = document.querySelector('.read-less');
    
    const activateReadMoreButton = () => {
      readMoreButton.classList.add('activated');
    }
    
    const deactivateReadMoreButton = () => {
      readMoreButton.classList.remove('activated');
    }
    
    readMoreButton.addEventListener('click', activateReadMoreButton);
    readLessButton.addEventListener('click', deactivateReadMoreButton);
    .read-more.activated,
    .read-more:not(.activated) ~ :is(p, button) {
      display: none;
    }
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quaerat, ex.</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quaerat, ex.</p>
    <button type="button" class="read-more">READ MORE</button>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quaerat, ex.</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quaerat, ex.</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quaerat, ex.</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quaerat, ex.</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quaerat, ex.</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quaerat, ex.</p>
    <button type="button" class="read-less">READ LESS</button>
    Login or Signup to reply.
  2. First, there is no need for a link placed inside a button.

    Second, one does not even need to classify the <div/> wrapper around the "READ MORE" button.

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

    • a) makes use of the functional :has() pseudo-class
    • b) does in addition register an event-handler at each of both buttons where both handlers take care of just the "READ MORE" related button-element’s disabled state.

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

    document
      .querySelector('#read-more')
      .addEventListener('click', ({ currentTarget: elmReadMore }) => {
        if (elmReadMore.matches(':not(:disabled)')) {
    
          elmReadMore.disabled = true;
        }
      });
    
    document
      .querySelector('#read-less')
      .addEventListener('click', () => {
        const elmReadMore = document.querySelector('#read-more');
    
        if (elmReadMore.matches(':disabled')) {
    
          elmReadMore.disabled = false;
        }
      });
    div:has(#read-more) ~ *,
    div:has(#read-more:disabled) {
      display: none;
    }
    div:has(#read-more:disabled) ~ * {
      display: revert;
    }
    <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 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>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search