[英]How to toggle display style using vanilla JS on multiple elements
我不知道如何從邏輯上寫出這個問題,我幾乎想出了togglw,但我在為別的事情苦苦掙扎。 當我單擊一個元素並打開它時,我想單擊另一個打開並關閉之前打開的元素。 但是,它不起作用。 每當我單擊另一個元素時,打開的元素就會關閉而不打開另一個元素。 基本上,我只想在單擊該特定元素時關閉該元素。 或者當我點擊另一個(有點工作)但在這種情況下也希望另一個打開,如果這有意義的話。 我被困在這一點上。
謝謝你的幫助。
這是我的代碼筆: https ://codepen.io/danosvk/pen/JjLEGMK
這是我的代碼:
const questions = document.querySelectorAll("section"); const answers = document.querySelectorAll(".answer"); toggle = false function open() { for (let i = 0; i < answers.length; i++) { answers[i].style.display = "none"; } toggle = !toggle this.lastElementChild.style.display = toggle ? "block" : "none" } questions.forEach((question) => question.addEventListener("click", open));
.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; }
<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>
使用toggle
不起作用,因為在顯示答案時它總是false
的。
相反,在擦除所有答案之前保存單擊選項的樣式,然后使用它來確定是否顯示答案。
如果this.lastElementChild.style.display
為''
(即第一次單擊菜單時),則將其設置為none
。
const questions = document.querySelectorAll("section"); const answers = document.querySelectorAll(".answer"); function open() { currentDisplay=this.lastElementChild.style.display||'none'; for (let i = 0; i < answers.length; i++) { answers[i].style.display = "none"; } if (currentDisplay=='none') this.lastElementChild.style.display = "block" } questions.forEach((question) => question.addEventListener("click", open));
.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; }
<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>
我會通過使用這個 CSS 規則來顯示答案而不是改變他們的內聯樣式來做到這一點:
.expanded .answer {
display: block;
}
...然后在包含常見問題解答的.card
元素上使用事件委托來捕獲其中任何位置的點擊; 如果點擊通過一個section
,請執行以下操作:
section
具有expanded
類,請將其刪除以取消擴展答案。section
沒有expanded
類,請將其從具有它的任何其他部分中刪除,然后將其添加到單擊的section
中。這是 JavaScript 部分:
const card = document.querySelector(".card");
card.addEventListener("click", (event) => {
const section = event.target.closest("section");
if (section) {
if (section.classList.contains("expanded")) {
// This is the expanded one, un-expand it
section.classList.remove("expanded");
} else {
// This isn't the expanded one, un-expand the expanded
// one (if any) and expand this one
document.querySelector("section.expanded")?.classList.remove("expanded");
section.classList.add("expanded");
}
}
});
注意querySelector
上的可選鏈接尋找擴展部分; 如果還沒有擴展部分,它就在那里。
現場示例:
const card = document.querySelector(".card"); card.addEventListener("click", (event) => { const section = event.target.closest("section"); if (section) { if (section.classList.contains("expanded")) { // This is the expanded one, un-expand it section.classList.remove("expanded"); } else { // This isn't the expanded one, un-expand the expanded // one (if any) and expand this one document.querySelector("section.expanded")?.classList.remove("expanded"); section.classList.add("expanded"); } } });
.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; } .expanded .answer { display: block; }
<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>
可能值得向section
添加一個類並在選擇器中使用它,以防頁面的其他部分使用section
,如下所示:
const card = document.querySelector(".card"); card.addEventListener("click", (event) => { const section = event.target.closest(".faq"); if (section) { if (section.classList.contains("expanded")) { // This is the expanded one, un-expand it section.classList.remove("expanded"); } else { // This isn't the expanded one, un-expand the expanded // one (if any) and expand this one document.querySelector(".faq.expanded")?.classList.remove("expanded"); section.classList.add("expanded"); } } });
.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; } .expanded .answer { display: block; }
<div class="card"> <h1 class="no">faq</h1> <section class="faq"> <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 class="faq"> <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 class="faq"> <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 class="faq"> <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 class="faq"> <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>
您還可以通過簡單地保留currentlyOpen
打開的部分的引用 (currentOpen) 並在事件偵聽器中使用它來修復它。
它只需要您更改一些 js 並保持相同的 css。
這里有一些代碼來解釋這個變化:
let currentlyOpen; // Keep track of the currently openend section.
function toggle() {
if (currentlyOpen) {
// Something currently open
currentlyOpen.lastElementChild.style.display = "none" // Close it
}
if (currentlyOpen === this) {
// The element the user clicked on is already opened, close it!
currentlyOpen.lastElementChild.style.display = "none" // Close it
currentlyOpen = undefined; // Delete it's refrence
return // And return (stop execution)
}
// Show clicked element
this.lastElementChild.style.display = "block"
// Store it for later
currentlyOpen = this
}
有關更多信息,請參閱代碼片段:
const questions = document.querySelectorAll("section"); const answers = document.querySelectorAll(".answer"); let currentlyOpen; function toggle() { if (currentlyOpen) { // Something currently open currentlyOpen.lastElementChild.style.display = "none" // Close it } if (currentlyOpen === this) { // Element is already open currentlyOpen.lastElementChild.style.display = "none" // Hide it currentlyOpen = undefined; // Delete it's refrence return // And return } // Show clicked element this.lastElementChild.style.display = "block" // Store it for later currentlyOpen = this } questions.forEach((question) => question.addEventListener("click", toggle));
.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; }
<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>
或托管在 jsfiddle 上的工作版本: https ://jsfiddle.net/fmr9tvw8/
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.