簡體   English   中英

如何在多個元素上使用 vanilla JS 切換顯示樣式

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM