2017-10-16 64 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