2016-06-10 1 views
4

У меня есть аккордеон, который работает очень хорошо, он хорошо выглядит на сайте и работает так, как должен. Тем не менее, я пытаюсь добавить к нему еще некоторые функции JavaScript, чтобы сделать его более профессиональным.Открывать только одну аккордеонную вкладку за один раз

В настоящее время аккордеон позволяет одновременно открывать несколько панелей, т. Е. Если я открою одну вкладку, а затем откройте другую вкладку, обе вкладки будут открыты одновременно. И единственный способ закрыть эти панели - это перехватить заголовок.

Что бы мне хотелось, это код JavaScript, который предотвращает одновременное открытие нескольких вкладок, поэтому, если я нажму на новую панель, сначала должен закрыть существующую открытую панель. Вот мой HTML код для аккордеона:

<div class="accordion"><b>Heading 1</b></div> 
<div class="panel"> 
    <p class="text-light">Text 1</p> 
</div> 
<div class="accordion"><b>Heading 2</b></div> 
<div class="panel"> 
    <p class="text-light">Text 2</p> 
</div> 

Вот мой код JavaScript в отдельный файл JavaScript, который в настоящее время позволяет несколько вкладок, чтобы быть открытыми в одно время

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

for (i = 0; i < acc.length; i++) { 
    acc[i].onclick = function() { 
     this.classList.toggle("active"); 
     this.nextElementSibling.classList.toggle("show"); 
    } 
} 

Не уверен, что если вам нужны все CSS, но есть CSS для отображения панели

div.panel.show { 
    display: block !important; 
} 

Надеюсь, кто-то может помочь! Заранее спасибо!

+0

Возможный дубликат [как сделать твиттер бутстрап аккордеон держать одну группу открытой] (http://stackoverflow.com/questions/15725717/how-do-you-make-twitter-bootstrap-accordion-keep-one- group-open) –

+1

Просто пройдите через все из них, установите их в 'inactive' и' hide'. Затем вы активируете и отобразите выбранный. – melancia

+0

@NalinAggarwal, где OP говорит, что он использует Bootstrap? –

ответ

3

Для достижения этой цели необходимо сбросить состояние аккордеона обратно в исходное состояние на каждый клик, прежде чем установить необходимые классы на перешедших элементов. Для этого вы можете извлечь функциональные возможности, чтобы установить имена классов в их собственную функцию и вызвать их по мере необходимости. Попробуйте это:

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

for (var i = 0; i < acc.length; i++) { 
    acc[i].onclick = function() { 
     var setClasses = !this.classList.contains('active'); 
     setClass(acc, 'active', 'remove'); 
     setClass(panel, 'show', 'remove'); 

     if (setClasses) { 
      this.classList.toggle("active"); 
      this.nextElementSibling.classList.toggle("show"); 
     } 
    } 
} 

function setClass(els, className, fnName) { 
    for (var i = 0; i < els.length; i++) { 
     els[i].classList[fnName](className); 
    } 
} 

Working example

+0

Он работает !! Спасибо огромное! Я очень ценю это. Есть еще одна функциональность, которую я бы хотел добавить, однако я не уверен, что ее возможно ... Когда вы нажимаете на заголовок аккордеона, я хочу, чтобы страница прокручивалась вниз до вершины этого открытого аккордеона, так что пользователь может видеть весь контент. Это что-то, что можно сделать? Опять же - огромное спасибо за ответ выше! –

+0

Рад помочь. Вы можете сделать это, добавив 'document.body.scrollTop = this.offsetTop;' обработчику кликов: https://jsfiddle.net/5h5evjpw/1/ –

+0

Эй! Спасибо за быстрый ответ!Я пробовал этот код, и он делает что-то странное, когда я нажимаю аккордеон, он позиционирует открытый аккордеон в нижней части моей страницы, поэтому я могу видеть заголовок, но текст в панели отключается от моего экрана, любой идеи о том, как это исправить? –

1

При выборе одного элемента вам просто нужно скрыть все из них заранее.

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

for (i = 0; i < acc.length; i++) { 
    acc[i].onclick = function() { 
     hideAll(); 

     this.classList.toggle("active"); 
     this.nextElementSibling.classList.toggle("show"); 
    } 
} 

function hideAll() { 
    for (i = 0; i < acc.length; i++) { 
     acc[i].classList.toggle("active", false); 
     acc[i].nextElementSibling.classList.toggle("show", false); 
    } 
} 
-2

вы должны покрыть панель с гармошкой, так что вы можете легко сделать это.

см это

html 
<div class="accordion"><b>Heading 1</b> 
    <div class="panel"> 
     <p class="text-light">Text 1</p> 
    </div> 
    </div> 
<div class="accordion"><b>Heading 2</b> 
    <div class="panel"> 
     <p class="text-light">Text 2</p> 
    </div> 
    </div> 

jquery: 
$('.accordion').click(function() { 
$(this).find('.panel').show(); 
$(this).siblings().find('.panel').hide(); 

}); 

Working example

+1

OP не использует 'jQuery'. – melancia

0
var acc = document.getElementsByClassName("accordion"); 
var i; 
var last; 
for (i = 0; i < acc.length; i++) { 
    acc[i].onclick = function() { 
     if(last){ 
      last.classList.toggle("active",false); 
      last.nextElementSibling.classList.toggle("show",false); 
     } 
     this.classList.toggle("active"); 
     this.nextElementSibling.classList.toggle("show"); 
     last=this; 
    } 
} 

переменной последняя будет отслеживать последний активный аккордеоне, так что вам не нужно повторять каждый аккордеоне и панель снова.

 Смежные вопросы

  • Нет связанных вопросов^_^