fade in list items sequentially with jQuery

Jonathan Miller picture Jonathan Miller · Apr 13, 2011 · Viewed 11k times · Source

I'm building a portfolio page that has a list of different projects (in an unordered list). On page load I want to have each "li" to fade in, one after another. I have achieved this like so:

var eT = 0;     
$('.everything').hide().each(function() {
    $(this).delay(eT).fadeIn('slow');
    eT += 200;
});

The problem I am having is that each li will have a class (or multiple) based on the type of work (web, print, etc) it represents. There is a navigation to the side that will allow you to filter the type of work to display. What I have encountered is that if I click the filters, while the animation is still loading in items, things get really messy.

Here is the template of the work page currently: http://jjaakk.miller-interactive.com/templates/work.html

I have been trying many things, but with limited success. Any thoughts on how to make this work in a more stable manner?

I tried adding .stop() on click, but it has not worked as I intended.

Answer

nhavens picture nhavens · Apr 13, 2011

I think the problem was related to a limitation with jQuery delay(). The following uses standard javascript setTimeout and clearTimeout as suggested by the jQuery delay() api.

<html>
<head>
    <script src="./jquery-ui-1.8.7.custom/js/jquery-1.4.4.min.js" type="text/javascript"></script>
    <script type="text/javascript">
        $(document).ready(function() {
            var timeOuts = new Array();
            var eT=200;
            function myFadeIn(jqObj) {
                jqObj.fadeIn('slow');
            }
            function clearAllTimeouts() {
                for (key in timeOuts) {
                    clearTimeout(timeOuts[key]);
                }
            }
            $('.everything').hide().each(function(index) {
                timeOuts[index] = setTimeout(myFadeIn, index*eT, $(this));
            });
            $('#something').click(function() {
                clearAllTimeouts();
                $('.everything').stop(true,true).hide();
                $('.something').each(function(index) {
                    timeOuts[index] = setTimeout(myFadeIn, index*eT, $(this));
                });
            });
        });
    </script>
    <style type="text/css">
        li.everything {width:40px;height:40px;background:#bbb;display:inline-block}
        li.something {width:80px;height:80px;background:#000;display:inline-block}
    </style>
</head>
<body>
    <button id="something">BLACK</button>
    <ul>
        <li class="everything"></li>
        <li class="everything something"></li>
        <li class="everything"></li>
        <li class="everything something"></li>
        <li class="everything"></li>
        <li class="everything something"></li>
        <li class="everything"></li>
        <li class="everything something"></li>
        <li class="everything"></li>
        <li class="everything something"></li>
    </ul>
</body>
</html>