簡體   English   中英

創建一個用於擴展和折疊手風琴的切換按鈕

[英]Creating a toggle button for expanding and collapsing an Accordion

我從W3Schools示例中為我正在處理的FAQ頁面創建了修改后的手風琴。 我是Java語言的新手,我需要一些幫助。 我想建立一個在展開所有面板和關閉所有面板之間切換的按鈕。 我可以從另一個人寫的創建“關閉所有面板”按鈕的博客文章中獲得一些幫助,但是現在我想構建一個函數,該功能可以在“全部關閉”和“全部打開”之間切換。 我還希望將所有這些都內聯,以便可以將這一頁代碼嵌入另一頁。 我已經附加了到目前為止創建的代碼。

<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<style>
.accordion {
    background-color: none;
    cursor: pointer;
    padding: 30px;
    width: 100%;
    border: #DADCE0;
    border-style: solid;
    border-width: 1px 0px 0px 0px;
    text-align: left;
    outline: none;
    font-family: Google Sans, sans-serif;
    font-weight: medium;
    font-size: 18px;
    line-height: 30px;
    transition: 0.4s;
    color: #1A73E8;
}

.accordion:hover {
    color: #174EA6;
}

.active {
    color: #174EA6;
    border-top-color: #DADCE0;
    border-bottom-color: #174EA6;
    border-style: solid;
    border-width: 1px 0px 2px 0px;
}

.accordion:after {
    font-family: 'Material Icons';
    content: "keyboard_arrow_down"; /*Google keyboard arrow down*/
    font-weight: bold;
    font-size: 24px;
    float: right;
    margin-left: 5px;
}

.active:after {
  font-family: 'Material Icons';
  content: "keyboard_arrow_up"; /*Google keyboard arrow up*/
  font-weight: bold;
  font-size: 24px;
  float: right;
  margin-left: 5px;
}

.panel {
    padding: 0px 18px;
    background-color: white;
    max-height: 0;
    overflow: hidden;
    transition: max-height 0.4s ease-out;
}

.closeall {
    float: right;
    margin: 1% 2% 0 0;
    cursor: pointer;
}

body {
    font-family: Roboto Light, sans-serif;
    line-height: 26px;
    font-size: 16px;
    color: #202124;
}

a {
    color: #4285f4;
}

</style>
</head>
<body>

<button  class="closeall" onclick="collapseall()">Close all</button>

<button class="accordion">Can I host my own events?</button>
<div class="panel">
  <p>Of course you can!</p>
</div>

<button class="accordion">Are the events for students?</button>
<div class="panel">
  <p>Yes, please see here.</p>
</div>

<button class="accordion">Are the events for teachers?</button>
<div class="panel">
  <p>Yes, please see here.</p>
</div>

<button class="accordion">Are the events for teachers 2?</button>
<div class="panel">
  <p>Yes, please see here 2.</p>
</div>

<script>
var acc = document.getElementsByClassName("accordion");
var i;

for (i = 0; i < acc.length; i++) {
  acc[i].onclick = function() {
    this.classList.toggle("active");
    var panel = this.nextElementSibling;
    if (panel.style.maxHeight){
      panel.style.maxHeight = null;
    } else {
      panel.style.maxHeight = panel.scrollHeight + "px";
    }
  }
}

function collapseall() {  //problematic part
    var x = document.getElementsByClassName("panel");
    var b;
    for (b = 0; b < x.length; b++) {
        x[b].style.maxHeight = null;
        x[b].previousElementSibling.classList.remove('active');
  }
}
</script>

</body>
</html>
function collapseall() {
    var x = document.getElementsByClassName("accordion");
    var y = 0;
    var b;

    for (b = 0; b < x.length; b++) {
       if(x[b].classList.contains('active'))y++;
    }

    if(x.length==y||y==0){
      for (b = 0; b < x.length; b++) {
         x[b].dispatchEvent(new Event('click'));
      }
    }else{
      for (b = 0; b < x.length; b++) {
         if(x[b].classList.contains('active'))
            x[b].dispatchEvent(new Event('click'));
      }
    }
}

好消息是您正在接近一個適當的解決方案, 我在這里為您實施了該解決方案。 實現該目標的捷徑可能看起來像

// Single reference to all panels 
// Getting them each time is heavy for the browser
var x = document.getElementsByClassName("panel");

// Indicator if we should open or close all panels
var isToggledOff = true;

然后,您需要兩個非常相似的功能來打開或折疊所有面板

function collapseAll() { 
    for (var b = 0; b < x.length; b++) {
        x[b].style.maxHeight = null;
        x[b].previousElementSibling.classList.remove('active');
  }
}

function expandAll() {
    for (var b = 0; b < x.length; b++) {
        x[b].style.maxHeight = "58px";
        x[b].previousElementSibling.classList.add('active');
   }
}

最后但並非最不重要的一點是,您需要邏輯來決定我們是否要打開或關閉所有面板以及將來如何處理它們

function toggle() {
   if (isToggledOff) this.expandAll();
   else this.collapseAll();
   isToggledOff = !isToggledOff
}

您可能需要考慮的其他事項

  1. 為什么需要設置該maxHeight? 將其添加到活動CSS類會更容易嗎?
  2. JS中的函數式編程具有超強的功能,為什么不使用.forEach()方法代替for循環? 這可能很棘手,但值得一課:)
  3. 為什么需要previousElementSibling屬性?
  4. 下次您添加問題時,請嘗試為人們提供最少的幫助,以使他們可以更輕松地了解問題所在。 在這種情況下,您可以從示例中剝離CSS代碼:)

替代方式

var x = Array.from(document.getElementsByClassName("panel"));
var isToggledOff = true;
function toggle() {
    x.forEach(el => el
        .previousElementSibling
        .classList
        [isToggledOff ? "add" : "remove"]('active')
    )
   isToggledOff = !isToggledOff
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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