1

There are many questions on this and I have tried them.

WHAT I AM TRYING TO DO

I am using jQuery fadeIn and fadeOut options to hide divs and show a list using the jquery below but the page keeps jumping to the top. The list that will be displayed is dynamic.

I tried with e.preventDefault(); and return false; but of no use.

I tried changing anchor tags to span tags but then the second onClick function doesn't work.

Is this because my content length is dynamic which is making it look like a jump or is it a real jump?

Thanks in advance.

HTML

<div id="action_bar">
    <div id="cart"><i class="fa fa-shopping-cart" aria-hidden="true"></i><div class="total">20</div></div>
    <a href="" id="nav">CATEGORIES</a>
    <div id="filter"><i class="fa fa-filter" aria-hidden="true"></i><div class="total">1</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>

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

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

CSS

ul.items
{
    padding:0;
    margin:0;
    display:none;
}
Ayan
  • 1,952
  • 2
  • 21
  • 58
  • The `items` fade out when you hit back? – Sandeep Nayak Jun 22 '16 at 09:44
  • The fading works fine but it keeps jumping to the top. – Ayan Jun 22 '16 at 09:49
  • If you're happy using the browser console, add a `debugger;` statement inside the `.on('click'..` handler and inside the 'success:' callback function - otherwise put some `alerts("step x")` (etc) in there to see exactly what's been called and when. – freedomn-m Jun 22 '16 at 10:02

4 Answers4

1

Your second .back onclick is never firing.

It doesn't work either time (as an a or span) - when it's an a, the default click will fire which will take you to the top.

This is because when you call $('.back').on('click'..) there isn't a .back element to wire up to as you've not yet added that class to your back button.

You need to use event delegation: https://stackoverflow.com/a/1688293/2181514

Change your event wire up to:

$("document").on("click", ".back", function....

which will then pick up dynamically changed classes

Community
  • 1
  • 1
freedomn-m
  • 21,261
  • 4
  • 28
  • 53
0

I doubt if your click event on .back is registered at all since when event is bound, .back does not exist. Hence its as good as a click on link which has no href.

You need to delegate click on .back to the document. This delegation is needed because you are adding the back class dynamically.

 $(document).on('click','.back', function(e){
        e.preventDefault();
        $('.items').fadeOut(300);
        $('.category').html(response).delay(400).fadeIn(300);
        $('#nav').html('CATEGORIES').removeClass('back');

    });
Sandeep Nayak
  • 4,277
  • 1
  • 18
  • 32
0

What you should do in html5, is use an anchor tag without the href attribute. In CSS you can use cursor: pointer to compensate for that. Then in JavaScript there's suddenly no need anymore for event.preventdefault

Tim Vermaelen
  • 6,001
  • 1
  • 22
  • 36
  • 1
    As a note: an `a` without an href cannot be focused using the keyboard `tab` key, so may fall foul or any accessbility requirements. In general, don't do this. – freedomn-m Jun 22 '16 at 09:50
  • That's correct, I used to do `href="void(0)"` so you don't need return false or preventDefault. if focus and usability (tablet/phone) is important => preventdefault is your friend to counter empty href or `href="#"` which makes the page jump to the top. – Tim Vermaelen Jun 22 '16 at 09:53
  • Yep the page I am making is responsive so I have to account for tablets and phones. – Ayan Jun 22 '16 at 09:54
0

A hacky solution is to set href="#/" on an anchor tag, which would work. However, using anchor tags where they are not needed (if you use <a> there should exist some clickable link) is not good practice for SEO.

Also, you could use e.preventDefault(), but use it on all functions, not only on back click.

However, the better practice is to use <input type="button" />, you eliminate those jumping problems and do better SEO.