Reputation: 287
I have some vanilla JavaScript that listens for a click and when there is a click, four things happen:
When another button is clicked, the reverse happens to the first-clicked button with the added class being removed, the 'aria-expanded' attribute is re-set to 'false', the div is hidden again (again set with CSS) and the 'after' text reverts to 'Read more'.
BUT, if the same button is clicked a second time, whilst the added class is removed as expected, and the div is hidden again, the 'aria-expanded' attribute is not re-set to 'false'. Can anyone explain why and tell me what I should be doing, please? (No jQuery, thanks).
const tips = Array.from(document.querySelectorAll('.toggle-button'));
tips.forEach((tip) => {
tip.addEventListener('click', () => {
tips
.filter((f) => f !== tip)
.forEach((f) => {
f.setAttribute('aria-expanded', false);
f.classList.remove('form-opened');
});
tip.setAttribute('aria-expanded', true);
tip.classList.contains('form-opened');
tip.classList.toggle('form-opened');
});
});
.toggle-button ~ .tips {
display: none;
}
button.toggle-button[aria-expanded="false"]:after {
content: "Read more";
}
.toggle-button.form-opened ~ .tips {
display: block;
margin-bottom: 16px;
}
button.toggle-button[aria-expanded="true"]:after {
content: "Close info";
cursor: pointer;
}
.visually-hidden {
border: 0;
padding: 0;
margin: 0;
position: absolute;
height: 1px;
width: 1px;
overflow: hidden;
white-space: nowrap;
display: inline-block;
}
<div class="toggle-box">
<label for="button-1" class="visually-hidden toggle-list">Open or Close info</label><button id="button-1" class="toggle-button" aria-expanded="false"></button>
<div class="tips">
Here is some text that is to be revealed </div>
</div>
<div class="toggle-box">
<label for="button-2" class="visually-hidden toggle-list">Open or Close info</label><button id="button-2" class="toggle-button" aria-expanded="false"></button>
<div class="tips">
Here is some text that is to be revealed </div>
</div>
<div class="toggle-box">
<label for="button-3" class="visually-hidden toggle-list">Open or Close info</label><button id="button-3" class="toggle-button" aria-expanded="false"></button>
<div class="tips">
Here is some text that is to be revealed </div>
</div>
I have seen some similar queries, but not quite the same or very old or they use jQuery.
Upvotes: 0
Views: 617
Reputation: 2103
Clicking a button only sets all other button's aria-expanded
attributes to false. You also have to toggle the state of the current button:
const tips = Array.from(document.querySelectorAll('.toggle-button'));
tips.forEach((tip) => {
tip.addEventListener('click', () => {
tips
.filter((f) => f !== tip)
.forEach((f) => {
f.setAttribute('aria-expanded', false);
f.classList.remove('form-opened');
});
// Toggle both aria-expanded attribute and form-opened class
tip.setAttribute(
"aria-expanded",
tip.getAttribute("aria-expanded") == 'true' ? 'false' : 'true'
);
tip.classList.toggle('form-opened');
});
});
Upvotes: 2