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

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

Допустим, у меня есть элементы A, B, C и D. И у каждого элемента есть два состояния: (1) состояние покоя [исходный размер и показ одного набора содержимого] и (2) активное [увеличение и отображение разного набора содержимого]. Если я нажимаю A, он переходит от A1 к A2. Теперь, если я нажму C, он перейдет из C1 в C2, и A должен перейти из A2 обратно в A1. У меня все отлично, но я не могу понять, как это сделать.

Я не уверен, что это мой jQuery или как я настроил HTML/CSS, но я в растерянности.

Я чувствую, что не очень хорошо объясняю, но это должно быть ясно, как только вы увидите пример.

Вот код, который я сейчас имею. Это также на jsfiddle в https://jsfiddle.net/vsjx5w5r/

HTML

<section id="grid">
    <div class="grid-sizer"></div>
    <div class="grid-item">
        <div class="grid-item-content">
            <div class="item-contents show">First test.</div>
            <div class="item-contents">Expanded</div>
        </div>  
    </div>

    <div class="grid-item">
        <div class="grid-item-content">
            <div class="item-contents show">Second test.</div>
            <div class="item-contents">Second Expanded</div>
        </div>  
    </div>

    <div class="grid-item">
        <div class="grid-item-content">
            <div class="item-contents show">Third test.</div>
            <div class="item-contents">Third Expanded</div>
        </div>
    </div>

    <div class="grid-item">
        <div class="grid-item-content">
            <div class="item-contents show">Fourth test.</div>
            <div class="item-contents">Fourth Expanded</div>
        </div>
    </div>

    <div class="grid-item">
        <div class="grid-item-content">
            <div class="item-contents show">Fifth test.</div>
            <div class="item-contents">Fifth Expanded</div>
        </div>
    </div>
</section>    

CSS

* {
  box-sizing: border-box;
}
#grid:after {
  content: '';
  display: block;
  clear: both;
}
.grid-item {
  float: left;  
  background: red;
  -webkit-transition: background 0.4s, box-shadow 0.4s;
          transition: background 0.4s, box-shadow 0.4s;
}
.grid-sizer,
.grid-item {
  width: 33%;
  padding-bottom: 33%;
  border: 1px solid #000;
}
.grid-item.is-expanded,
.grid-item.is-expanded .grid-item-content {
  width: 66%;
  padding-bottom: 66%;
}
.grid-item.is-expanded {
  z-index: 2;
}
.grid-item-content {
  position: absolute;
  top: 0;
  left: 0;
  width: 100% !important;
  height: 100%;
  background: yellow;
}
@media (max-width: 767px) {
  .grid-sizer,
  .grid-item {
    width: 50%;
    padding-bottom: 50%;
    border: 1px solid #000;
  } 
  .grid-item.is-expanded,
  .grid-item.is-expanded .grid-item-content {
    width: 100%;
    padding-bottom: 100%;
  } 
}
.grid-item-content div.item-contents {
  display: none;
  transition: all .5s ease;
}
.grid-item-content div.item-contents.show {
  display: block;
}

Jquery

$(document).ready(function () { 
  var $grid = $('#grid').isotope({
    itemSelector: '.grid-item',
    percentPosition: true,
    masonry: {
      columnWidth: '.grid-sizer'
    }
  });

  $grid.on( 'click', '.grid-item-content', function() {
    $(this).parent('.grid-item').toggleClass('is-expanded').siblings().removeClass('is-expanded');      
    $(this).children().toggleClass('show');

    // This is the part that isn't working correctly.
    if ($(this).parent('.grid-item.is-expanded').siblings().children().children('.item-contents:nth-child(2)').hasClass('show')) {
        $(this).parent('.grid-item').siblings().children().children().toggleClass('show');
    };

    $grid.isotope('layout');
  });
}); 

1 ответ

Решение

Лично я бы сделал это так:

// First give .grid-item elements a 'setContent' behaviour, which can be triggered.
$('.grid-item').on('setContent', function() {
    $(this).find('.grid-item-content').children().removeClass('show') // remove 'show' from both children.
    .eq(+$(this).hasClass('is-expanded')) // .eq(0) or .eq(1) selects first or second child.
    .addClass('show'); // add 'show' to the selected child.
});

// Invoke isotope() on #grid.
var $grid = $('#grid').isotope({
    itemSelector: '.grid-item',
    percentPosition: true,
    masonry: {
        columnWidth: '.grid-sizer'
    }
})
// and attach a delegated click handler
.on('click', '.grid-item-content', function() {
    $(this).parent('.grid-item').toggleClass('is-expanded') // toggle the class
    .siblings().removeClass('is-expanded') // remove 'is-expanded' from the parent's siblings
    .addBack() // add the original .grid-item back into the selection
    .trigger('setContent'); // trigger the 'setContent' behaviour on all .grid-item elements.

    $grid.isotope('layout');
});

Обновленная скрипка

Все хитрые вещи заключаются в двух длинных цепочках jQuery, которые выглядят намного лучше без комментариев.

Другие вопросы по тегам