web-dev-qa-db-fra.com

Ouvrez seulement un onglet d'accordéon à la fois

J'ai un accordéon qui fonctionne vraiment bien, il a l'air bien sur le site et fonctionne comme il se doit. Toutefois, j'essaie d'ajouter des fonctionnalités JavaScript supplémentaires afin de lui donner un aspect plus professionnel.

Actuellement, l'accordéon vous permet d'avoir plusieurs panneaux ouverts en même temps, c'est-à-dire que si j'ouvre un onglet, puis un autre, les deux onglets seront ouverts en même temps. Et la seule façon de fermer ces panneaux, est de cliquer à nouveau sur l'en-tête.

Ce que je voudrais, c'est un code JavaScript qui empêche l'ouverture simultanée de plusieurs onglets. Par conséquent, si je clique sur un nouveau panneau, il devrait d'abord fermer le panneau ouvert existant. Voici mon code HTML pour l'accordéon:

<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>

Voici mon code JavaScript dans un fichier JavaScript séparé qui permet actuellement d'ouvrir plusieurs onglets à la fois.

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");
    }
}

Pas sûr si vous avez besoin de tous les CSS, mais voici le CSS pour montrer le panneau

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

J'espère que quelqu'un pourra vous aider! Merci d'avance!

4
Usman Zafar

Pour ce faire, vous devez réinitialiser l'état de l'accordéon à son état d'origine à chaque clic, avant de définir les classes requises sur les éléments cliqués. Pour ce faire, vous pouvez extraire une fonctionnalité afin de définir les noms de classe sur leur propre fonction et de l'appeler si nécessaire. Essaye ça:

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);
    }
}

Exemple de travail

6
Rory McCrossan
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;
    }
}

variable last suivra le dernier accordéon actif, vous n'avez donc pas besoin de répéter chaque accordéon et chaque panneau.

2
Colin

Lorsque vous sélectionnez un élément, il vous suffit de tous les masquer au préalable.

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);
    }
}
1
melancia