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>
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 ...
a) makes use mainly of the functional :has()
pseudo-class and the Subsequent-sibling combinator
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
property/state.
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>