简体   繁体   中英

jQuery Cycling Through Multiple States of Siblings Children on Click

My problem is that I'm trying to switch content from one state when the element is at its original size to different content when its at its expanded or active size.

So let's say I have elements A, B, C & D. And each element has two states, (1)resting [original size and showing one set of content] and (2)active [enlarged and showing different set of content]. If I click A, it goes from A1 to A2. Now if I click C, it goes from C1 to C2 and A should go from A2 back to A1. I've got the sizing thing down fine but its the switching of the content that I can't figure out how to do.

I'm not sure if its my jQuery or the way I've set up the HTML/CSS but I'm at a loss.

I feel like I'm not explaining it well, but it should be clear once you see the example.

Here's the Code I have right now. It's also on jsfiddle at 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');
  });
}); 

Personally, I would do it like this :

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

Updated fiddle

All the tricky stuff is in two longish jQuery chains, which look a whole lot better without the comments.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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