如何用Vanilla JS实现多元素互斥式显示切换功能?
FAQ折叠面板问题解决方案
问题描述
我已经掌握了基础的toggle功能,但遇到了一个问题:点击某元素展开后,再点击另一个元素时,希望能展开新元素的同时关闭之前展开的那个。但现在的效果是,点击新元素时,已展开的会关闭,但新元素却没打开。我想要的是两种效果之一:要么只有点击当前展开的元素才能关闭它;要么点击其他元素时,自动关闭当前展开项并打开新的。目前卡在这了。
方案一:点击其他元素自动切换(关闭旧项,打开新项)
问题根源在于你使用了全局的toggle变量,每次点击都会反转这个变量,导致新元素的显示状态被错误切换。去掉全局变量,直接针对当前元素和其他元素处理即可:
修改后的JavaScript代码
const questions = document.querySelectorAll("section"); const answers = document.querySelectorAll(".answer"); function open() { const currentAnswer = this.lastElementChild; const isCurrentlyOpen = currentAnswer.style.display === "block"; // 关闭所有答案面板 answers.forEach(answer => answer.style.display = "none"); // 如果当前面板原本是打开的,就关闭;否则打开它 currentAnswer.style.display = isCurrentlyOpen ? "none" : "block"; } questions.forEach((question) => question.addEventListener("click", open));
如果不需要点击当前项关闭,只切换到新项,代码可以更简洁:
const questions = document.querySelectorAll("section"); const answers = document.querySelectorAll(".answer"); function open() { // 关闭所有答案 answers.forEach(answer => answer.style.display = "none"); // 打开当前点击的答案 this.lastElementChild.style.display = "block"; } questions.forEach((question) => question.addEventListener("click", open));
方案二:仅允许点击当前展开项关闭(支持多面板同时展开)
如果希望点击其他元素时不关闭已展开的面板,只处理当前点击的元素,代码如下:
const questions = document.querySelectorAll("section"); function open() { const currentAnswer = this.lastElementChild; // 切换当前答案的显示状态 currentAnswer.style.display = currentAnswer.style.display === "block" ? "none" : "block"; } questions.forEach((question) => question.addEventListener("click", open));
原代码参考
HTML
<div class="card"> <h1 class="no">faq</h1> <section> <p class="question">How many team members can i invite?</p> <img class="arrow" src="./images/icon-arrow-down.svg" alt="" /> <p class="answer"> You can invite up to 2 additional users on the Free plan. There is no limit on team members for the Premium plan. </p> </section> <section> <p class="question">What is the maximum file upload size?</p> <img class="arrow" src="./images/icon-arrow-down.svg" alt="" /> <p class="answer"> No more than 2GB. All files in your account must fit your allotted storage space. </p> </section> <section> <p class="question">How do I reset my password?</p> <img class="arrow" src="./images/icon-arrow-down.svg" alt="" /> <p class="answer"> Click “Forgot password” from the login page or “Change password” from your profile page. A reset link will be emailed to you. </p> </section> <section> <p class="question">Can I cancel my subscription?</p> <img class="arrow" src="./images/icon-arrow-down.svg" alt="" /> <p class="answer"> Yes! Send us a message and we’ll process your request no questions asked. </p> </section> <section> <p class="question">Do you provide additional support?</p> <img class="arrow" src="./images/icon-arrow-down.svg" alt="" /> <p class="answer"> Chat and email support is available 24/7. Phone lines are open during normal business hours. </p> </section> </div>
CSS
.card { width: 20.4375rem; background-color: #ffffff; border-radius: 1.4375rem; margin: auto; padding: 132px 24px 48px; text-align: center; transform: translateY(-125px); } section { display: flex; align-items: center; justify-content: space-between; border-bottom: 1px solid #e8e8ea; flex-wrap: wrap; } p { color: var(--main-text-color); font-size: 0.75rem; } .answer { flex-basis: 100%; text-align: left; display: none; }
内容的提问来源于stack exchange,提问作者DanyTheNoobCoder
相关产品推荐
相关产品推荐

