0

I am trying to hide a category list on click of a particular category and load the respective contents. The loading, fading in and fading out works fine but the problem is that whenever I fade Out the div the page scroll position goes to the element before the hidden div and whenever new elements are faded in the scroll position remains in the position of the last element. What to do so that the scroll position remains the same and a text or gif can be shown so that the user can see that some work is going on before the new elements are faded in?

HERE IS MY paste.

HTML

<div id="main_container">
    <div id="coupon">
        <div id="left_content">
            <div id="coupon_heading">COUPON&nbsp;&#9733;&#9733;&#9733; </div>
            <div id="coupon_text">USE <strong><i>NEW20</i></strong> TO GET AN ADDITIONAL 20% OFF</div>
        </div>
        <div id="right_content">
            <div id="exclamation">OPENING<br>SALE</div>
        </div>
    </div>


    <div id="content">
        <div id="category1" class="category" data-categories="SPL">
            <img src="images/c_w.png"><div class="category_description">Chef's Special</div>
        </div>

        <div id="category2" class="category" data-categories="LCH">
            <img src="images/l_w.png"><div class="category_description">Lunch</div>
        </div>

        <div id="category3" class="category" data-categories="SNK">
            <img src="images/s_w.png"><div class="category_description">Snacks</div>
        </div>

        <div id="category4" class="category" data-categories="DNR">
            <img src="images/d_w.png"><div class="category_description">Dinner</div>
        </div>
        <ul class="items">
            <!-- Menu List -->
        </ul>
    </div>
</div>

JS

<script type="text/javascript">
$(document).ready(function(){
    $('body').on('click', '.category', function(){
        var category = $(this).data('categories');
        //alert(category);
        $('.category').fadeOut(300);
        $.ajax({
               type: "POST",
               url: "./assets/listproducts.php",
               data: {cat: category},
               cache: false,
               success: function(response){
                   //console.log(response);
                  $('#nav').html('Back').addClass('back');
                  $('.items').html(response).delay(400).fadeIn(300);
               }
        });
    });

    $('#action_bar').on('click', '.back', function(e){
        e.preventDefault();
        //alert('click');
        $('.items').fadeOut(300);
        $('.category').delay(400).fadeIn(300);
        $('#nav').html('CATEGORIES').removeClass();
    });
});
</script>

UPDATE

I tried using a callback in fadeOut but didn't work.

       success: function(response){
           //console.log(response);
           $('.category').fadeOut(300, function(){
                $('#nav').html('Back').addClass('back');
                $('.items').html(response).delay(400).fadeIn(300);
           });
       }
Ayan
  • 2,738
  • 3
  • 35
  • 76
  • It would be great if you could make a JSFiddle out of the snippets you provided. – xtrinch Jun 24 '16 at 15:23
  • I dont think it will be of any help because the data being fetched is from a php script. I can make a paste. – Ayan Jun 24 '16 at 15:25
  • Or you could do [this](http://stackoverflow.com/questions/7194408/how-can-i-use-the-jsfiddle-echo-feature-with-jquery) – Dipen Shah Jun 24 '16 at 15:27
  • 1
    This happens because the fading out element is still there until it fades out completely. Hence at the transitioning time, both of them are taking space for some duration. This is avoided by placing both the divs using `absolute` position. If that is not possible, you can first fadeOut one div, then in the callback i.e. when the fadeOut completes, then you call fadeIn on another div. – Mohit Bhardwaj Jun 24 '16 at 15:34
  • @Mohit Bhardwaj can you show an example? – Ayan Jun 24 '16 at 15:40
  • @Ayan Check out this fiddle https://jsfiddle.net/24o32htu/1/ This should be behaving like your current code. Now, if you go to css and change the `position: static` to `position: absolute` for the fading divs, it would work fine. – Mohit Bhardwaj Jun 24 '16 at 15:47
  • Yes its kind of what's happening. @DipenShah I am making a paste of my entire code as in fiddle its giving me some error in Js asking me to use plain JS and even .html(string) would not be allowed. – Ayan Jun 24 '16 at 15:59
  • Remember that fadeOut changed display to none which means it takes up no space in the DOM. On the other hand, visibility;hidden keeps the element as the same size but just not visible. Is this what you want? – nurdyguy Jun 24 '16 at 16:15
  • @nurdyguy If I use visibility:none then it would create a gap in between. So that's not what will I like. I would like that when an user clicks on any category the category list is hidden followed by a loading gif to show that something is happening and then fadeIn the fetched list from the PHP file while maintaing the scroll position to the beginning of the list. – Ayan Jun 24 '16 at 16:19
  • @nurdyguy any ideas?? – Ayan Jun 24 '16 at 16:41
  • @Ayan Then display:none is the correct value. The issue is that you are changing the size of the overall DOM. Since the size is larger than the screen, that will affect the scrolling. You could use the [, complete ] overload for fadeOut to trigger a scroll/nav event. This would be a good place to add a # nav. You could also do it with a scroll event but the # nav would probably be cleaner. – nurdyguy Jun 24 '16 at 17:04
  • @nurdyguy, a small snippet would help me in understanding. Am not at all good at JS. – Ayan Jun 24 '16 at 17:07
  • @Ayan Check out this question. Several of the answers offer possible might work for you. Basically, you'll do $(myElem).fadeOut(100, scollfunc()); and then define scrollFunc using one of these types of snipets. http://stackoverflow.com/questions/4801655/how-to-go-to-a-specific-element-on-page – nurdyguy Jun 24 '16 at 18:22

1 Answers1

0

It seems that the following works just the way I want. If there is something really wrong in the code I wrote, please correct me.

$(document).ready(function(){
    $('body').on('click', '.category', function(){
        var category = $(this).data('categories');
        //alert(category);
        $.when($('.category').fadeOut(500)).done(function(){
            //Try showing a loader
        });
        $.ajax({
               type: "POST",
               url: "./assets/listproducts.php",
               data: {cat: category},
               cache: false,
               success: function(response){
                   //console.log(response);
                        $('#nav').html('Back').addClass('back');
                        $('#content').append($('<ul class="items">').append(response)).delay(400).fadeIn(500);
               }
        });
    });

    $('#action_bar').on('click', '.back', function(e){
        e.preventDefault();
        $.when($('.items').fadeOut(500)).done(function(){
            $('.items').remove();
            $('#nav').html('CATEGORIES').removeClass();
            $('#content').append($('.category').css('display','block')).delay(400).fadeIn(300);
        });
    });
});
</script>
Ayan
  • 2,738
  • 3
  • 35
  • 76