simplest way to lazy load long <ul> with many <li>s

14,580

As you've said this is just for effect here is a nice little solution I found a while ago.

Let's assume your markup is like this

<ul id="yourlist">
<li>list item</li> ... etc

1) Slice the first twenty elements and hide the rest.

$("#yourlist li").slice(20).hide();

2) We set two variables. Min and Max (the difference being 20 at all times). This will load the next 20 in the list. It then checks for window scroll and if the window height comes within 400 px of the bottom of the page (or div if you change the code) then it will run the next function which is to slice the min to max and fadeIn those items. Then it counts on so that it's ready to run the next time.

var mincount = 20;
var maxcount = 40;


$(window).scroll(function() 
                    {
                    if($(window).scrollTop() + $(window).height() >= $(document).height() - 400) {
                            $("#yourlist li").slice(mincount,maxcount).fadeIn(1200);

mincount = mincount+20;
maxcount = maxcount+20;

}
});

Here is a JS FIDDLE OF IT WORKING http://jsfiddle.net/ymyx8/1/ with some background colours on the li's so you can see it loading

Edit: to add loading DIV

As per your question in the comments: The issue is that nothing is actually 'loading'. Usually when you see this occurring it's because an AJAX call is made and the loading is shown and hidden on the success function. The effect can be mimicked using a delay like so:

JS FIDDLE http://jsfiddle.net/ymyx8/3/

You could also to it on callback functions on the fadeOut etc.

Share:
14,580
irfan mir
Author by

irfan mir

Updated on June 04, 2022

Comments

  • irfan mir
    irfan mir almost 2 years

    What is the simplest way to lazy load a long list ( ) of many (65+) list items?

    By lazy load I mean only load the list items that are visible in the viewport. Once a list item is visible in the viewport then load it.

    I've looked at many infinite scrolling and lazy load plugins, but none of them seem to be just for a really long list.

    They all seems to be for a really long list of images, or a list that has pagination with previous and next buttons.

    My HTML is just a list of text with many list items like so:

    <ul>
        <li>list item</li>
        <li>list item</li>
        <li>list item</li>
        <li>list item</li>
        <li>list item</li>
        <li>list item</li>
        <li>list item</li>
        <li>list item</li>
        <li>list item</li>
        <li>list item</li>
        <li>list item</li>
        <li>list item</li>
        <li>list item</li>
        <li>list item</li>
        <li>list item</li>
        <li>list item</li>
        <li>list item</li>
        <li>list item</li>
        <li>list item</li>
        <li>list item</li>
        <li>list item</li>
        <li>list item</li>
        <li>list item</li>
        <li>list item</li>
        <li>list item</li>
        <li>list item</li>
        <li>list item</li>
        <li>list item</li>
        <li>list item</li>
        <li>list item</li>
        <li>list item</li>
        <li>list item</li>
        <li>list item</li>
        <li>list item</li>
        <li>list item</li>
        <li>list item</li>
        <li>list item</li>
        <li>list item</li>
        <li>list item</li>
        <li>list item</li>
        <li>list item</li>
        <li>list item</li>
        <li>list item</li>
        <li>list item</li>
        <li>list item</li>
        <li>list item</li>
        <li>list item</li>
        <li>list item</li>
        <li>list item</li>
        <li>list item</li>
        <li>list item</li>
        <li>list item</li>
        <li>list item</li>
        <li>list item</li>
        <li>list item</li>
        <li>list item</li>
        <li>list item</li>
        <li>list item</li>
        <li>list item</li>
        <li>list item</li>
        <li>list item</li>
        <li>list item</li>
        <li>list item</li>
        <li>list item</li>
        <li>list item</li>
        <li>list item</li>
        <li>list item</li>
        <li>list item</li>
        <li>list item</li>
        <li>list item</li>
        <li>list item</li>
        <li>list item</li>
    <ul>
    

    I would greatly appreciate any and all help in writing the javascript or jquery so that only those that are currently in the viewport are loaded and then rest are hidden and then when teh user scrolls and others come into view in the viewport, they are loaded. And, if possible, display a <div>loading...</div> while those are loading.

    The part that I really do not know how to do is to load or show only what is visible in the viewport in the beginning and then one could load, with jQuery's .load(), or show, with jQuery's .show() those that are in the viewport. But I don't know how to tell what is in the viewport and what is not.

    I would greatly appreciate any and all help with this!

    Thanks in Advance!

  • irfan mir
    irfan mir almost 11 years
    Is there a way I can display a div at the bottom of the the list that is currently visible while the items underneath are loading? The div would just have the text loading... and when the other items loading, it is hidden. Do you know how to do that part?
  • James
    James almost 11 years
    You have a few problems in your markup. 1) In your script tag you have </body></html> present. 2) You are only selecting the UL in your code not the LI. Use this: ------> $('#main > ul li').slice(6).hide(); var minCount = 6; var maxCount = 12; $(window).scroll(function(){ if($(window).scrollTop()+$(window).height() >= $(document).height() - 320){ $('#main > ul li').slice(minCount, maxCount).fadeIn(); minCount+=6; maxCount+=6; } });
  • James
    James almost 11 years
    You can also add some time in MS in the fadeIn() to make it seem more apparent like fadeIn(500) will be half a second.
  • irfan mir
    irfan mir almost 11 years
    Yes, I looked at my code a second time and saw I missing the closing tag and the document.ready. I added those and now it works. Yes, I agree the fading should be delayed more.
  • James
    James almost 11 years
    It might also flow better if you lower height from bottom of page it runs at. Maybe change -320 to just - 20. I think this is a nicer effect for your whole page: ------>>> $('#main > ul li').slice(6).hide(); var minCount = 6; var maxCount = 12; $(window).scroll(function(){ if($(window).scrollTop()+$(window).height() >= $(document).height() - 20){ $('#main > ul li').slice(minCount, maxCount).fadeIn(500); minCount+=6; maxCount+=6; } });
  • irfan mir
    irfan mir almost 11 years
    what about displaying a <div>loading...</div> underneath the part that has loaded and while the list items underneath are loading? Also, what part do I change if I want more list items to show in the beginning before the user scrolls ?
  • irfan mir
    irfan mir almost 11 years
    Thank you for all the additional help, it is looking quite nice now. What do I change if I want more list items to show in the beginning? When all the others one are hidden. How can I show 16 and then once the user scrolls start show every 16 after that?
  • James
    James almost 11 years
    Change -> $('#main > ul li').slice(6).hide() - the 6 is how many is showing when the page is ready. So if you want it to show 16 it would be $('#main > ul li').slice(16).hide()... But then you need to change your initial variables too. Your initial variable needs to be var minCount = 16; var maxCount = 32; then at end of the script put minCount+=16; maxCount+=16; See my edit for displaying DIV. Also don't forget to mark this as correct if I answered your question of how to do this effect.
  • irfan mir
    irfan mir almost 11 years
    I will mark this as the correct answer in one second. But first, I am doing .slic(16).hide() but only 4 are showing. Why? Here is a link: dl.dropboxusercontent.com/u/270523/help/untitled%20folder/…
  • James
    James almost 11 years
    The problem is your selectors. You have nested lists. So each LI has another 3 LI in it... 16/(3+1) = 4. So you're getting 4. Try changing your selector from the ul > li to the div class result... eg $('#main > ul .result')
  • Matthew Woodard
    Matthew Woodard about 10 years
    Can this be accomplished with onclick() rather than scroll?
  • James
    James about 10 years
    Yes @MatthewWoodard - you would remove the $(window) and if statement and replace with a click function on a trigger like this: $('.yourtrigger').click(function(){ $("#yourlist li").slice(mincount,maxcount).fadeIn(1200);
  • Jean R.
    Jean R. about 6 years
    Oh my god, it's simply beautiful ! Simple, smart and efficient !