2017-10-16 107 views
1

我目前正在開發更復雜的手風琴。手風琴應有4個按鈕(0-3部分),內容單獨(0-3)。通過點擊「部分0」應該顯示「lorem ipsum 0」。通過點擊「第1部分」,內容「lorem ipsum 0」將被替換爲「lorem ipsum 1」。Javascript:從動態生成的ID中提取的動態手風琴內容

最後一個網站將有一個未知數量的行,每個行包含4個手風琴。這意味着,腳本必須是動態的。

我的方法是使用JS生成ID,將該屬性設置爲每個面板,然後再次調用它們以使手風琴起作用。但我只能打電話給所有的內容(如JSFiddle)或者只是循環中的最後一個內容。

如何在不丟失佈局的情況下顯示/替換每個手風琴的內容?

也許這是一個更好的方法來實現這一點?

HTML:

<div class="row"> 

    <div class="three columns"> 
    <button class="accordion">Section 0</button> 
    </div> 

    <div class="three columns"> 
    <button class="accordion">Section 1</button> 
    </div> 

    <div class="three columns"> 
    <button class="accordion">Section 2</button> 
    </div>  

    <div class="three columns"> 
    <button class="accordion">Section 3</button> 
    </div> 

</div> 

<div class="row"> 
    <div class="twelve columns"> 
    <div class="panel"> 
     <p>Lorem ipsum 0...</p> 
    </div> 
    </div> 
    <div class="twelve columns"> 
    <div class="panel"> 
     <p>Lorem ipsum 1...</p> 
    </div> 
    </div> 
    <div class="twelve columns"> 
    <div class="panel"> 
     <p>Lorem ipsum 2...</p> 
    </div> 
    </div> 
    <div class="twelve columns"> 
    <div class="panel"> 
     <p>Lorem ipsum 3...</p> 
    </div> 
    </div> 
</div> 

JS:

var acc = document.getElementsByClassName("accordion"); 
for (var i = 0; i < acc.length; i++) { 
    acc[i].onclick = function() { 
     this.classList.toggle("active"); 

     var writeID = document.getElementsByClassName("panel"); 
     for (var y = 0; y < writeID.length; y++) { 
      var newID = "demo-"+y; 
      writeID[y].setAttribute("id", newID); 

      var panel = document.getElementById(newID); 

      if (panel.style.maxHeight){ 
       panel.style.maxHeight = null; 
      } else { 
       panel.style.maxHeight = panel.scrollHeight + "px"; 
      } 
     } 
    } 
} 

我還創建了一個JSFiddle

任何幫助表示感謝!

乾杯 最大

編輯:我真的很感激任何形式的幫助在這裏。我試圖通過關閉和forEach解決問題,但沒有解決。如果我必須澄清以上任何內容,我很樂意回答任何問題。

以下是代碼的當前狀態。它給我的所有內容,但我想只有一次每個手風琴:

var acc = document.getElementsByClassName("accordion"); 
for (var i = 0; i < acc.length; i++) { 
    acc[i].onclick = function() { 
    this.classList.toggle("active"); 

     for (var i = 0; i < acc.length; i++) { 
     var panel = document.getElementById("demo-"+i); 
     if (panel.style.maxHeight){ 
      panel.style.maxHeight = null; 
     } else { 
      panel.style.maxHeight = panel.scrollHeight + "px"; 
     } 
     }; 
    } 
} 

或者換句話說,我試圖做到這一點,但在一個動態的方式

var acc = document.getElementsByClassName("accordion"); 

acc[0].onclick = function() { 
    this.classList.toggle("active"); 
    var panel = document.getElementById("demo-0"); 
    if (panel.style.maxHeight){ 
    panel.style.maxHeight = null; 
    } else { 
    panel.style.maxHeight = panel.scrollHeight + "px"; 
    }  
} 

acc[1].onclick = function() { 
    this.classList.toggle("active"); 
    var panel = document.getElementById("demo-1"); 
    if (panel.style.maxHeight){ 
    panel.style.maxHeight = null; 
    } else { 
    panel.style.maxHeight = panel.scrollHeight + "px"; 
    }  
} 
+0

讓我試着在給出我的方法之前瞭解您的問題!每個按鈕的內容都是動態的,我認爲它是對的?與按鈕相同? – funcoding

+0

是的,內容將是動態的。它可以是文字或圖像。按鈕將遵循一個模式,因此它們將具有固定的名稱(如示例中所示)。 – Max

+0

我現在讀了很多關於javascript loop enclosure的內容,但它仍然無法弄清楚。任何人提供一些幫助?謝謝! – Max

回答

0

您可以添加自定義屬性與節號(data-section=3)的按鈕,並用它來使用正確的數據打開正確的面板

var data = ["lorem ipsum ipsum", "lorem lorem lorem", "blah blah blah"]; 
 
formatData(data); 
 

 
function formatData(data) { 
 
    data.forEach(function(text, index) { 
 
    var buttonHTML = "<div class='three columns'>" + 
 
     "<button class='accordion' data-section=" + index + ">Section " + index + "</button>" + 
 
     "</div>"; 
 

 
    var accordionHTML = "<div class='twelve columns'>" + 
 
     "<div id='panel" + index + "' class='panel'>" + 
 
     "<p>" + text + "</p>" + 
 
     "</div>" + 
 
     "</div>"; 
 
    document.getElementById("buttonRow").insertAdjacentHTML('beforeend', buttonHTML); 
 
    document.getElementById("panelRow").insertAdjacentHTML('beforeend', accordionHTML); 
 
    }) 
 
    var acc = document.getElementsByClassName("accordion"); 
 
    for (var i = 0; i < acc.length; i++) { 
 
    acc[i].onclick = function() { 
 
     this.classList.toggle("active"); 
 
     var sectionNum = this.getAttribute("data-section"); 
 
     var currentPanel = document.getElementById("panel" + sectionNum); 
 
     if (currentPanel.style.maxHeight) { 
 
     currentPanel.style.maxHeight = null; 
 
     } else { 
 
     currentPanel.style.maxHeight = currentPanel.scrollHeight + "px"; 
 
     } 
 
    } 
 
    } 
 
}
.democlass { 
 
    color: red; 
 
} 
 

 
#demo-0 { 
 
    color: red; 
 
} 
 

 
#demo-1 { 
 
    color: blue; 
 
} 
 

 
#demo-2 { 
 
    color: green; 
 
} 
 

 
#demo-3 { 
 
    color: magenta; 
 
} 
 

 

 
/* Accordion 
 
–––––––––––––––––––––––––––––––––––––––––––––––––– 
 
https://www.w3schools.com/howto/howto_js_accordion.asp 
 
*/ 
 

 

 
/* Style the buttons that are used to open and close the accordion panel */ 
 

 
button.accordion { 
 
    background-color: #eee; 
 
    color: #444; 
 
    cursor: pointer; 
 
    width: 100%; 
 
    text-align: left; 
 
    border: none; 
 
    outline: none; 
 
    transition: 0.4s; 
 
} 
 

 

 
/* Add a background color to the button if it is clicked on (add the .active class with JS), and when you move the mouse over it (hover) */ 
 

 
button.accordion.active, 
 
button.accordion:hover { 
 
    background-color: #ccc; 
 
} 
 

 

 
/* Style the accordion panel. Note: hidden by default */ 
 

 
div.panel { 
 
    padding: 0 18px; 
 
    background-color: white; 
 
    /* display: none; 
 
*/ 
 
    max-height: 0; 
 
    overflow: hidden; 
 
    transition: max-height 0.2s ease-out; 
 
} 
 

 
.container { 
 
    position: relative; 
 
    width: 100%; 
 
    /*max-width: 1200px;*/ 
 
    margin: 0 auto; 
 
    padding: 0 20px; 
 
    box-sizing: border-box; 
 
} 
 

 
.column, 
 
.columns { 
 
    width: 100%; 
 
    float: left; 
 
    box-sizing: border-box; 
 
} 
 

 

 
/* For devices larger than 400px */ 
 

 
@media (min-width: 400px) { 
 
    .container { 
 
    width: 85%; 
 
    padding: 0; 
 
    } 
 
} 
 

 

 
/* For devices larger than 550px */ 
 

 
@media (min-width: 550px) { 
 
    .container { 
 
    width: 95%; 
 
    } 
 
    .column, 
 
    .columns { 
 
    margin-left: 4%; 
 
    } 
 
    .column:first-child, 
 
    .columns:first-child { 
 
    margin-left: 0; 
 
    } 
 
    .one.column, 
 
    .one.columns { 
 
    width: 4.66666666667%; 
 
    } 
 
    .two.columns { 
 
    width: 13.3333333333%; 
 
    } 
 
    .three.columns { 
 
    width: 22%; 
 
    } 
 
    .four.columns { 
 
    width: 30.6666666667%; 
 
    } 
 
    .five.columns { 
 
    width: 39.3333333333%; 
 
    } 
 
    .six.columns { 
 
    width: 48%; 
 
    } 
 
    .seven.columns { 
 
    width: 56.6666666667%; 
 
    } 
 
    .eight.columns { 
 
    width: 65.3333333333%; 
 
    } 
 
    .nine.columns { 
 
    width: 74.0%; 
 
    } 
 
    .ten.columns { 
 
    width: 82.6666666667%; 
 
    } 
 
    .eleven.columns { 
 
    width: 91.3333333333%; 
 
    } 
 
    .twelve.columns { 
 
    width: 100%; 
 
    margin-left: 0; 
 
    } 
 
    .one-third.column { 
 
    width: 30.6666666667%; 
 
    } 
 
    .two-thirds.column { 
 
    width: 65.3333333333%; 
 
    } 
 
    .one-half.column { 
 
    width: 48%; 
 
    } 
 
    /* Offsets */ 
 
    .offset-by-one.column, 
 
    .offset-by-one.columns { 
 
    margin-left: 8.66666666667%; 
 
    } 
 
    .offset-by-two.column, 
 
    .offset-by-two.columns { 
 
    margin-left: 17.3333333333%; 
 
    } 
 
    .offset-by-three.column, 
 
    .offset-by-three.columns { 
 
    margin-left: 26%; 
 
    } 
 
    .offset-by-four.column, 
 
    .offset-by-four.columns { 
 
    margin-left: 34.6666666667%; 
 
    } 
 
    .offset-by-five.column, 
 
    .offset-by-five.columns { 
 
    margin-left: 43.3333333333%; 
 
    } 
 
    .offset-by-six.column, 
 
    .offset-by-six.columns { 
 
    margin-left: 52%; 
 
    } 
 
    .offset-by-seven.column, 
 
    .offset-by-seven.columns { 
 
    margin-left: 60.6666666667%; 
 
    } 
 
    .offset-by-eight.column, 
 
    .offset-by-eight.columns { 
 
    margin-left: 69.3333333333%; 
 
    } 
 
    .offset-by-nine.column, 
 
    .offset-by-nine.columns { 
 
    margin-left: 78.0%; 
 
    } 
 
    .offset-by-ten.column, 
 
    .offset-by-ten.columns { 
 
    margin-left: 86.6666666667%; 
 
    } 
 
    .offset-by-eleven.column, 
 
    .offset-by-eleven.columns { 
 
    margin-left: 95.3333333333%; 
 
    } 
 
    .offset-by-one-third.column, 
 
    .offset-by-one-third.columns { 
 
    margin-left: 34.6666666667%; 
 
    } 
 
    .offset-by-two-thirds.column, 
 
    .offset-by-two-thirds.columns { 
 
    margin-left: 69.3333333333%; 
 
    } 
 
    .offset-by-one-half.column, 
 
    .offset-by-one-half.columns { 
 
    margin-left: 52%; 
 
    } 
 
}
<div class="container"> 
 

 
    <div id="buttonRow" class="row"> 
 

 
    </div> 
 

 
    <div id="panelRow" class="row"> 
 

 
    </div> 
 

 
</div> 
 
<!-- /container -->

+0

感謝您對這個主題的想法。內容(lorem ipsum)需要是動態的,並從cms中獲取,所以我猜這是行不通的。不管怎樣,謝謝你! – Max

+0

最大我更新了答案,使其對您的數據更具動態性。我把你的數據作爲一個字符串數組,但是你可以把它變成另一種類型的對象 –

+0

謝謝安德魯!我最終用jQuery做了這件事 - 一位朋友幫助我解決了一些代碼。感謝您的時間和精力 – Max