简体   繁体   English

Javascript手风琴关闭页眉/面板(如果选中)

[英]Javascript accordion close header/panel if selected

I would like the accordion to close if the same header/panel is clicked, the function I've added hides the prior panel if a new header/panel is selected, but it won't hide itself. 如果要单击相同的标题/面板,我希望手风琴关闭,如果选择了新的标题/面板,我添加的功能将隐藏先前的面板,但是不会隐藏自身。

Not looking to use any jquery, would like this to stay pure javascript 不希望使用任何jquery,想要保留纯JavaScript

I've added another function hide() but haven't had any success yet, what would I need to change in the hide() for this to work, or could it all be done from the for loop? 我添加了另一个函数hide(),但还没有成功,我需要在hide()中进行什么更改才能使其工作,或者可以全部通过for循环来完成?

 function accordion() { let acc = document.getElementsByClassName("accordion") let i; for (i = 0; i < acc.length; i++) { acc[i].addEventListener("click", function() { hide() this.classList.toggle("active") let panel = this.nextElementSibling; if (panel.style.display == "block") { panel.style.display = "none" } else { panel.style.display = "block" } }) } function hide() { for (i = 0; i < acc.length; i++) { acc[i].classList.toggle("active", false); acc[i].nextElementSibling.classList.toggle("show", false); acc[i].nextElementSibling.style.display = "none" } } } 
 .accordion { background-color: #eee; color: #444; cursor: pointer; padding: 18px; width: 100%; border: none; text-align: left; outline: none; font-size: 15px; transition: 0.4s; } .active, .accordion:hover { background-color: #ccc; } .panel { padding: 0 18px; display: none; background-color: white; overflow: hidden; } 
 <body onload="accordion()"> <button class="accordion">Section 1</button> <div class="panel"> <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p> </div> <button class="accordion">Section 2</button> <div class="panel"> <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p> </div> <button class="accordion">Section 3</button> <div class="panel"> <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p> </div> </body> 

I simplified your code a bit using forEach() and ternaries. 我使用forEach()和三元数简化了代码。

The problem was that you were hiding all accordions in your hide() function, but you should not hide the currently opened accordion so you can simply toggle its state. 问题在于您将所有手风琴hide()hide()函数中,但是您不应该隐藏当前打开的手风琴,因此您可以简单地切换其状态。

 document.querySelectorAll('.accordion').forEach((acc, i, all) => { acc.addEventListener('click', () => { hideOthers(acc); acc.classList.toggle('active'); const panelStyle = acc.nextElementSibling.style; panelStyle.display = panelStyle.display === 'block' ? 'none' : 'block'; }) function hideOthers(me) { all.forEach(acc => { if (acc !== me) { acc.classList.remove('active'); acc.nextElementSibling.classList.remove('show'); acc.nextElementSibling.style.display = 'none'; } }); } }); 
 .accordion { background-color: #eee; color: #444; cursor: pointer; padding: 18px; width: 100%; border: none; text-align: left; outline: none; font-size: 15px; transition: 0.4s; } .active, .accordion:hover { background-color: #ccc; } .panel { padding: 0 18px; display: none; background-color: white; overflow: hidden; } 
 <button class="accordion">Section 1</button> <div class="panel"> <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p> </div> <button class="accordion">Section 2</button> <div class="panel"> <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p> </div> <button class="accordion">Section 3</button> <div class="panel"> <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p> </div> 

You will need to keep a track of the currently clicked <div> . 您将需要跟踪当前单击的<div> Also, you can use the css combinator + as .active+.panel . 另外,您可以将CSS组合器+用作.active+.panel See code below 见下面的代码

 function accordion() { let acc = document.querySelectorAll(".accordion") for (let i = 0; i < acc.length; i++) { acc[i].addEventListener("click", function() { for (let j = 0; j < acc.length; j++) { if (j !== i) acc[j].classList.remove("active") } this.classList.toggle("active") }) } } 
 .accordion { background-color: #eee; color: #444; cursor: pointer; padding: 18px; width: 100%; border: none; text-align: left; outline: none; font-size: 15px; transition: 0.4s; } .active, .accordion:hover { background-color: #ccc; } .panel { padding: 0 18px; display: none; background-color: white; overflow: hidden; } .active+.panel { display: block; } 
 <body onload="accordion()"> <button class="accordion">Section 1</button> <div class="panel"> <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p> </div> <button class="accordion">Section 2</button> <div class="panel"> <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p> </div> <button class="accordion">Section 3</button> <div class="panel"> <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p> </div> </body> 

You can simplify your code: 您可以简化代码:

  1. css: .active + .panel -> Adjacent sibling so you don't need to use javascript for this part. css:.active + .panel-> 相邻的兄弟,因此您无需在此部分使用javascript。

  2. in listener remember if current was active, if it was not - "activate" it 在侦听器中,记住当前是否处于活动状态,如果不是,则“激活”它

 function accordion(){ let acc = document.getElementsByClassName("accordion") let i; for (i = 0; i < acc.length; i++) { acc[i].addEventListener("click", function() { let currentActive = this.classList.contains("active"); hide(); !currentActive && this.classList.add("active"); }) } function hide() { for (i = 0; i < acc.length; i++) { acc[i].classList.remove("active"); } } } 
 .accordion { background-color: #eee; color: #444; cursor: pointer; padding: 18px; width: 100%; border: none; text-align: left; outline: none; font-size: 15px; transition: 0.4s; } .active, .accordion:hover { background-color: #ccc; } .panel { padding: 0 18px; display: none; background-color: white; overflow: hidden; } .active + .panel { display: block; } 
 <body onload="accordion()"> <button class="accordion">Section 1</button> <div class="panel"> <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p> </div> <button class="accordion">Section 2</button> <div class="panel"> <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p> </div> <button class="accordion">Section 3</button> <div class="panel"> <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p> </div> </body> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM