web-dev-qa-db-fra.com

Comment faire pour que le sélecteur nième enfant saute les divs cachés

J'ai quelques blocs aléatoires. Chaque fois qu'un bloc tombe dans une nouvelle rangée, je le fais paraître différent. Lorsque l'utilisateur clique sur un bouton, je masque quelques blocs par display:none, et le problème se produit. Le nth-child selector compte également les éléments cachés.

Existe-t-il un moyen d'ignorer ces blocs spécifiques, afin que chaque ligne ait à nouveau un style différent? Ceci est un exemple de mon scénario similaire.

$('.hide-others').click(function () {
    $('.css--all-photo').toggleClass('hidden');
})
.board-item--inner {
    height:200px;
    background:tomato;
    text-align:center;
    color:#fff;
    font-size:33px;
    margin-bottom:15px;
    border:2px solid tomato;
}
@media (min-width:768px) and (max-width:991px) {
    .board-item:nth-child(2n+1) .board-item--inner {
        border:2px solid #000;
        background:yellow;
        color:#000;
    }
}
@media (min-width:992px) and (max-width:1199px) {
  .board-item:nth-child(3n+1) .board-item--inner {
    border:2px solid #000;
    background:yellow;
    color:#000;
  }
}
@media (min-width:1200px) {
  .board-item:nth-child(4n+1) .board-item--inner {
    border:2px solid #000;
    background:yellow;
    color:#000;
  } 
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="container">
    <div class="form-group">
        <button class="btn btn-info hide-others" type="button">Hide others</button>
    </div>
    <div class="row">
        <div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 board-item photos-board-item">
            <div class="board-item--inner">1</div>
        </div>
        <div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 board-item photos-board-item">
            <div class="board-item--inner">2</div>
        </div>
        <div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 board-item photos-board-item css--all-photo">
            <div class="board-item--inner">3</div>
        </div>
        <div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 board-item photos-board-item">
            <div class="board-item--inner">4</div>
        </div>
        <div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 board-item photos-board-item">
            <div class="board-item--inner">5</div>
        </div>
        <div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 board-item photos-board-item css--all-photo">
            <div class="board-item--inner">6</div>
        </div>
        <div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 board-item photos-board-item">
            <div class="board-item--inner">7</div>
        </div>
        <div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 board-item photos-board-item css--all-photo">
            <div class="board-item--inner">8</div>
        </div>
        <div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 board-item photos-board-item">
            <div class="board-item--inner">9</div>
        </div>
        <div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 board-item photos-board-item">
            <div class="board-item--inner">0</div>
        </div>
        <div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 board-item photos-board-item">
            <div class="board-item--inner">10</div>
        </div>
    </div>
    <div>

Passez simplement par l'extrait de code ou EXTERNAL FIDDLE , et vous aurez ma question.

Je recherche spécifiquement une solution CSS pure. Veuillez fournir un violon pour vos réponses! Et je ne peux pas supprimer ces blocs de façon permanente, mon utilisateur a la possibilité de filtrer les fichiers en cliquant sur le bouton, c'est pourquoi caché et scénario illustré.

24
Deepak Yadav

Lorsque l'utilisateur clique sur un bouton, je masque quelques blocs par display:none, Et le problème se produit. Le sélecteur nth-child Compte également les éléments cachés.

Existe-t-il un moyen d'ignorer ces blocs spécifiques, afin que chaque ligne ait à nouveau un style différent?

Le problème est que le sélecteur nth-child() examine tous les frères et sœurs sous le même parent, quel que soit le style. Peu importe que vous ayez appliqué display: none Car CSS ne supprime pas l'élément du DOM, et donc c'est toujours un frère.

De la spécification:

6.6.5.2. :nth-child() pseudo-classe

La notation de pseudo-classe :nth-child(an+b) représente un élément qui a un frère + b-1 avant dans l'arborescence du document, pour tout entier positif ou valeur nulle de n, et a un élément parent. (c'est moi qui souligne)

Pour que les règles nth-child Que vous avez déclarées fonctionnent après qu'un utilisateur a cliqué pour masquer les divs, vous devez supprimer les divs cachées du DOM, afin qu'elles n'existent plus comme frères et sœurs.

Dans votre question, vous demandez une solution CSS uniquement. Mais dans vos commentaires, vous dites que le HTML est ouvert aux changements. Vous utilisez également un peu de jQuery pour masquer les éléments.

Avec une petite ligne de code ajoutée à votre jQuery, le problème peut être résolu:

$('.hidden').remove();

La méthode .remove() retire les éléments (et ses descendants) du DOM. Dans ce cas, il supprime tous les éléments avec une classe hidden.


[~ # ~] correction [~ # ~]

Le problème avec remove() est que les éléments extraits du DOM avec cette méthode ne peuvent pas être restaurés, ce qui rompt la fonction de basculement.

Heureusement, jQuery propose une alternative: detach() .

La méthode .detach() est la même que .remove(), sauf que .detach() conserve toutes les données jQuery associées aux éléments supprimés. Cette méthode est utile lorsque des éléments supprimés doivent être réinsérés dans le DOM ultérieurement.

Donc, si nous remplaçons le code d'origine ...

$('.hide-others').click(function () {
    $('.css--all-photo').toggleClass('hidden');
})

... avec ce code ...

var divs;

$('.photos-board-item').each(function(i){
    $(this).data('initial-index', i);
});

$('.hide-others').on('click', function () {
    if(divs) {
        $(divs).appendTo('.row').each(function(){
            var oldIndex = $(this).data('initial-index');
            $('.photos-board-item').eq(oldIndex).before(this);
        });
        divs = null;
    } else {
        divs = $('.css--all-photo').detach();
    }
});

... la grille fonctionne comme prévu. (crédit de code: @ JosephMarikle )

[~ # ~] démo [~ # ~]

Maintenant, quels que soient les divs ou le nombre qui sont cachés, ils peuvent être activés et désactivés sans perturber la conception visuelle car le sélecteur nth-child Ne compte que les frères et sœurs "visibles". Aucune modification au CSS. Aucune modification du HTML.

18
Michael_B

Je le ferais avec une combinaison du sélecteur :nth-of-type Et une petite modification de votre fonction bascule.

L'idée de base n'est pas de supprimer ces éléments .css--all-photo Du DOM mais de les envelopper dans des conteneurs <hidden>. Et unwrap() pour restaurer l'ensemble complet. Dans ce cas, :nth-of-type Fera exactement ce que vous avez fait avec :nth-child.

var state = false;

$('.hide-others').click(function () {
    if( !state ) {
      $('.css--all-photo').wrap('<hidden>');
      state = true;
    } else {
      $('hidden').unwrap();
      state = false;
    }
})
hidden { display:none; } 

.board-item--inner {
    height:200px;
    background:tomato;
    text-align:center;
    color:#fff;
    font-size:33px;
    margin-bottom:15px;
    border:2px solid tomato;
}
@media (min-width:768px) and (max-width:991px) {
    div.board-item:nth-of-type(2n+1) .board-item--inner {
        border:2px solid #000;
        background:yellow;
        color:#000;
    }
}
@media (min-width:992px) and (max-width:1199px) {
  div.board-item:nth-of-type(3n+1) .board-item--inner {
    border:2px solid #000;
    background:yellow;
    color:#000;
  }
}
@media (min-width:1200px) {
  div.board-item:nth-of-type(4n+1) .board-item--inner {
    border:2px solid #000;
    background:yellow;
    color:#000;
  } 
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="container">
    <div class="form-group">
        <button class="btn btn-info hide-others" type="button">Hide others</button>
    </div>
    <div class="row">
        <div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 board-item photos-board-item">
            <div class="board-item--inner">1</div>
        </div>
        <div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 board-item photos-board-item">
            <div class="board-item--inner">2</div>
        </div>
        <div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 board-item photos-board-item css--all-photo">
            <div class="board-item--inner">3</div>
        </div>
        <div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 board-item photos-board-item">
            <div class="board-item--inner">4</div>
        </div>
        <div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 board-item photos-board-item">
            <div class="board-item--inner">5</div>
        </div>
        <div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 board-item photos-board-item css--all-photo">
            <div class="board-item--inner">6</div>
        </div>
        <div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 board-item photos-board-item">
            <div class="board-item--inner">7</div>
        </div>
        <div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 board-item photos-board-item css--all-photo">
            <div class="board-item--inner">8</div>
        </div>
        <div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 board-item photos-board-item">
            <div class="board-item--inner">9</div>
        </div>
        <div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 board-item photos-board-item">
            <div class="board-item--inner">0</div>
        </div>
        <div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 board-item photos-board-item">
            <div class="board-item--inner">10</div>
        </div>
    </div>
    <div>
2
c-smile

Ce que vous cherchez, c'est un n-de-classe qui n'existe malheureusement pas! Lorsque vous basculez la classe cachée avec JS, c'est la seule différence entre les enfants cachés et les enfants affichés, vous devez donc dire à css de compter les divs de certaines classes, (disons "montré"), mais malheureusement, css nth-child selector doesn ' t faites très attention aux classes de l'enfant. Vous pouvez lire plus ici .

0
Ramtin Gh