Patrick Manser
Patrick Manser

Reputation: 1183

Hide and show elements on windows resize

I have a list of categories. This list contains >5 elements and when I am on desktop, it should only show 5 elements and the list is expandable with a button (that's been already taken care of). When I resize the window to a certain size, it should only show 4 elements of the list. This I got working. However, when I resize the window again to a wider size, the 5th element doesn't reappear.

$(document).ready(function() {
	$('div.category-wrapper').each(function() {
  	var numEl = $(this).find('a').length;
    if (numEl > 5) {
    	$('a', this).eq(4).nextAll().hide().addClass('shop-category-toggleable');
    }
  });
  
  $(window).resize(function() {
    if ($('#tablet-indicator').is(':visible')) {
      $('div.category-wrapper').each(function() {
        var numEl = $(this).find('a').length;
        if (numEl > 4) {
          $('a', this).eq(3).nextAll().hide().addClass('shop-category-toggleable');
        }
      });
    }
  });

  $(window).resize(function() {
    if ($('#desktop-indicator').is(':visible')) {
      $('div.category-wrapper').each(function() {
        var numEl = $(this).find('a').length;
        console.log(numEl);
        if (numEl > 5) {
          $('a', this).eq(4).nextAll().hide().addClass('shop-category-toggleable');
        }
      });
    }
  });
});
 .category-wrapper .shop-category {
   display: block;
 }
 
 #tablet-indicator,
 #desktop-indicator {
   width: 10px;
   height: 10px;
 }
 
 #tablet-indicator {
   background-color: green;
 }
 
 #desktop-indicator {
   background-color: red;
 }

@media (min-width: 300px) {
  #tablet-indicator {
    display: block;
  }
  #desktop-indicator {
    display: none;
  }
}

@media (min-width: 600px) {
  #tablet-indicator {
    display: none;
  }
  #desktop-indicator {
    display: block;
  }
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="category-wrapper">
  <a href="#" class="shop-category">shop category</a>
  <a href="#" class="shop-category">shop category</a>
  <a href="#" class="shop-category">shop category</a>
  <a href="#" class="shop-category">shop category</a>
  <a href="#" class="shop-category">shop category</a>
  <a href="#" class="shop-category">shop category</a>
  <a href="#" class="shop-category">shop category</a>
  <a href="#" class="shop-category">shop category</a>
  <a href="#" class="shop-category">shop category</a>
  <a href="#" class="shop-category">shop category</a>
  <a href="#" class="shop-category">shop category</a>
</div>

<div id="desktop-indicator"></div>
<div id="tablet-indicator"></div>

I already tried putting the if ($('#desktop-indicator').is(':visible')) part as an else if part to the first resize function and also as its own if. The current code doesn't work either and I doubt that I really need two resize() blocks, but oh the despair.

Resizing might be easier here, same code as above: https://jsfiddle.net/v7obssas/

Upvotes: 0

Views: 54

Answers (1)

Robert Koritnik
Robert Koritnik

Reputation: 105029

You're only hiding categories

What you forgot to do is to show your categories before hiding them. So whenever you do

$('a', this)
    .eq(4)
    .nextAll()
    .hide()
    .addClass('shop-category-toggleable');

you're not showing elements that were already hidden. That's why when you get to four elements only, you always stay with four as you haven't shown any of the hidden ones before reapplying visible state.

You should therefore do this

$('a', this)
    .show() // add this extra line to initially show all categories
    .eq(4)
    .nextAll()
    .hide()
    .addClass('shop-category-toggleable');

Don't worry that this code will show all your categoris because it executes synchronously which means by the time your script hands over processing to rendering all your elements will have correct styling applied for rendering engine to display correctly.

$(document).ready(function() {
	$('div.category-wrapper').each(function() {
  	var numEl = $(this).find('a').length;
    if (numEl > 5) {
    	$('a', this).show().eq(4).nextAll().hide().addClass('shop-category-toggleable');
    }
  });
  
  $(window).resize(function() {
    if ($('#tablet-indicator').is(':visible')) {
      $('div.category-wrapper').each(function() {
        var numEl = $(this).find('a').length;
        if (numEl > 4) {
          $('a', this).show().eq(3).nextAll().hide().addClass('shop-category-toggleable');
        }
      });
    }
  });

  $(window).resize(function() {
    if ($('#desktop-indicator').is(':visible')) {
      $('div.category-wrapper').each(function() {
        var numEl = $(this).find('a').length;
        console.log(numEl);
        if (numEl > 5) {
          $('a', this).show().eq(4).nextAll().hide().addClass('shop-category-toggleable');
        }
      });
    }
  });
});
 .category-wrapper .shop-category {
   display: block;
 }
 
 #tablet-indicator,
 #desktop-indicator {
   width: 10px;
   height: 10px;
 }
 
 #tablet-indicator {
   background-color: green;
 }
 
 #desktop-indicator {
   background-color: red;
 }

@media (min-width: 300px) {
  #tablet-indicator {
    display: block;
  }
  #desktop-indicator {
    display: none;
  }
}

@media (min-width: 600px) {
  #tablet-indicator {
    display: none;
  }
  #desktop-indicator {
    display: block;
  }
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="category-wrapper">
  <a href="#" class="shop-category">shop category</a>
  <a href="#" class="shop-category">shop category</a>
  <a href="#" class="shop-category">shop category</a>
  <a href="#" class="shop-category">shop category</a>
  <a href="#" class="shop-category">shop category</a>
  <a href="#" class="shop-category">shop category</a>
  <a href="#" class="shop-category">shop category</a>
  <a href="#" class="shop-category">shop category</a>
  <a href="#" class="shop-category">shop category</a>
  <a href="#" class="shop-category">shop category</a>
  <a href="#" class="shop-category">shop category</a>
</div>

<div id="desktop-indicator"></div>
<div id="tablet-indicator"></div>

An advisable change

Although I wouldn't use Javascript to do this. You're already using CSS media queries (which BTW has a bug when you go below 300px both indicators are visible) so why not use media queries to limit the number of categories being displayed as well?

Upvotes: 1

Related Questions