Search code examples
jqueryjquery-selectors

Fade in list items one at a time in different lists


I've been trying to make some cool set of lists show an item at a time. But if I do that using the next method, it gets all slow and laggy. Is there a way to do that smoothly?

Here's a CodePen of the thing and the code below:

HTML (emmet)

(.outer>(ul#list$>(li.left>h3{title$})+(li.center>p{some text})+(li.right>p{some other text}))*5)+button#show{SHOAW}

SCSS

$height: 50px;

*{box-sizing:border-box}
body{font-family:sans-serif}

.outer{
  width:100%;


  ul{
    width:100%;
    list-style:none;
    padding:0;
    margin:0;
    height:$height;

    li{
      float:left;
      width: (100%/3);
      background-color: whitesmoke;
      height:$height;
      border-left:solid thin #e1e1e1;
      text-align:center;
      &.center, &.right {
        display:none;
      }
      &:first-child{
        border-left:none;
      }
    }
  }
}

jQuery

$(document).ready(function() {
    $('#show').click(function() {

      $('.center, .right').first().show('fast', function showNext () {
        $('.outer ul *').next('.center, .right').show('fast', showNext);
      });

    });

});

Solution

  • I've worked out a solution! Turns out the .next method is not appropriate for the whole thing because at the end of the first list, it cannot go for the next. I tried using using .parent to move out and come back in inside a for, but it opens every item simultaneously. SetTimeout also was no dice, since JavaScript doesn't wait for the previous iteration to finish (it would set the time for everything and do everything at once).

    So the solution as as follows (also in CodePen):

    var c=-1; //il counter - c=1, show center; c=-1, show right
    var p=1;  //ul counter - c=-1, p++
      $('#show').click( function() {
          $('#list' + p +' li').first().show('fast',   // first of all (list1.ul.center)
              function showNext(){
                c*=-1;        // switch li (right)
                if (c==1) {
                  $('#list' + p + ' li').next('ul .center').show('fast', showNext);
                } else {      // c= -1, show .right
                  p++;        //next list
                  $('#list' + (p-1) + ' li').next('ul .right').show('fast', showNext);
                }
              }
          );
        } 
      );
    
    $('#hide').click( function() {
      $('ul .center, ul .right').hide('fast');
      c=-1; p=1;
    });
    

    The idea is to use next only to move inside the current list. Then, if the next is finished with the current, move to the next using a variable.

    A little (waaaay) more complicated then I expected, but it rendered nicely and smoothly.