6

I have a list of blog posts and the number is reaching 25+ but it's all in the one page so I need to try and build a lazy loader.

I have tried various plugins but none are working

http://jsfiddle.net/tara_irvine/S9GGz/6/

http://jsfiddle.net/tara_irvine/S9GGz/9/

http://jsfiddle.net/tara_irvine/S9GGz/13/

Is there a way to check the top value of a div and if it's in view then a class is added so the div becomes visible (page load the div is hidden)

I have looked at these posts but after trying out various solutions none have worked for me.

How to check if an element is in the view of the user with jquery Position of Div in relation to the Top of the Viewport

If anyone can shed some light on this I would be very grateful. I don't know where I am going wrong.

Thanks very much

Community
  • 1
  • 1
Tara Irvine
  • 823
  • 3
  • 22
  • 42

5 Answers5

7

jQuery Waypoints is a nice plugin for reacting on elements coming into view; they even have a lazy-loading example.

Tgr
  • 25,494
  • 11
  • 77
  • 108
  • Sorry I don't mean to be a pain but is this a lazy load? I don't want an infinite scroll just for the div to fadeIn when it's in view. Thanks for the speedy response. – Tara Irvine Aug 15 '12 at 12:20
  • Well lazy load means that you don't load the content until the user reaches there; you seem to have some sort of "lazy display" in mind. The idea is the same, you can use Waypoints and use `$x.show()` instead of `$x.load()`. (Personally, I would rather use some sort of pager, that seems easier for the user to understand.) – Tgr Aug 15 '12 at 12:45
2

I don't know how your setup is, but i would suggest using jquery to find out distance from top of page this would be:

var scrollTop     = $(window).scrollTop(),
    elementOffset = $('#my-element').offset().top,
    distance      = (elementOffset - scrollTop);

as per this stack overflow post : Determine distance from the top of a div to top of window with javascript

apply that to your 25th post by putting numbered id's or names on each (I supposed the page is PHP generated).

then use ajax to load more blog posts when the distance reaches a certain amount.

EDIT: you can use jquery greater-than to hide them:

$(".element-class:gt(24)").css("display","none");​

documentation here: http://api.jquery.com/gt-selector/

then just if you scroll past a certain scroll-top, you can just set

$("visible-element").css("display","block")

EDIT 2: TRY THIS FIDDLE - http://jsfiddle.net/addiktedDesign/KjNnY/

Community
  • 1
  • 1
AddiktedDesign
  • 512
  • 2
  • 16
1

http://archive.plugins.jquery.com/project/lazyload is a list of lazy loading pliugins but it's more for images loading.

what you can try is have each blogpost element hidden except for the first three, then on

jpalala
  • 340
  • 3
  • 13
  • Sorry I need to be able to lazy load div's based on their y position, at least I think that's the solution. Do you know if Lazy Load can load more than just images? – Tara Irvine Aug 15 '12 at 09:52
1

I have tried getting the top of an element and displaying content when it is in viewport, the content could be just hidden or loaded from ajax call. Try this code. You can experiment with sensitivity variable to see what works for you best:

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js"></script>
    <script type="text/javascript">
        var processScroll = true;
        var sensitivity = 10;
        function handleScroll()
        {
            if (processScroll) {
                processScroll = false;
                topHidden = $('.block_hidden:first').offset().top;
                if(($(window).scrollTop() + $(window).height() ) > (topHidden + sensitivity))
                {
                    console.log('show now');
                    $('.block_hidden:first').removeClass('block_hidden').addClass('block');
                }
            }

            processScroll = true;
        }

        $(document).ready(function()
        {
            $(window).scroll(handleScroll);
        });
    </script>

    <style>
        .block_hidden{
            width:300px;
            background: green;
            margin:5px;
            visibility: hidden;
            height: 10px !important;
        }

        .block{
            height: 200px;
            width:300px;
            background: green;
            margin:5px;
        }
    </style>

</head>
<body>
    <div class="block"></div>
    <div class="block"></div>
    <div class="block"></div>
    <div class="block_hidden"></div>
    <div class="block_hidden"></div>
    <div class="block_hidden"></div>
    <div class="block_hidden"></div>
    <div class="block_hidden"></div>
    <div class="block_hidden"></div>
</body>
</html>
Rohit
  • 356
  • 1
  • 5
1

You are asking about Lazy Loading.

Well the answer must include a server side. Your question does not specify what type of server side language you are using. In my answer I will use some basic PHP code for mocking random blog posts.

lazy loading means that we only load what the user can see, and later load more data when needed.

loading data means - requesting it from a server. This usually involves AJAX but not necessarily. (although you probably can use AJAX ). JQuery has a wonderful ajax interface.

The biggest question is - what should trigger my next load - hence all the plugins.

I took Tgr's advice and implemented a lazy load with waypoints. I even used waypoint tutorial for lazy loading as Tgr suggested (give Tgr more points please).

You can see my implementation at my site

What I made was mock blog posts with changing title. Each time the user scrolls down enough, I get more posts from the server.

I added a download link for my source so you can download and start playing with it. just run main.html and you're good to go.

The file more_posts.php generates a lorem ipsum post with a random title. ( I needed some fake content to have a scroll on the page ).

It looks like this

<h1> This is post number <?php echo uniqid("",true)?> </h1>

<div style="color:red">
Lorem ipsum dolor .... Quisque ut pretium nibh.
</div>

<div style="color:blue">
Lorem ipsum dolor .... Quisque ut pretium nibh.
</div>

As you can see the only PHP code I have is to add something random to the title.

This should look familiar to you since you already have 25+ posts in your blog.

The real logic lies in main.html - the HTML part looks like so

<section id="container">

    </section>

    <footer>
        <nav>
            <ul>
                <!-- Hijack this link for the infinite scroll -->
                <li class="more"><a href="more_posts.php" title="Traditional navigation link">Next Page</a></li>
            </ul>
        </nav>
    </footer>

The idea is you have section which contains the first few posts - and gives you some scrolling on the page. At bottom you have a more link within a footer, that when JavaScript is disabled should act as a regular "next" link.

Waypoint uses this link to trigger the next load. Whenever the link is about to show on screen we will use ajax to get the next post automatically.

So the JavaScript part looks like so :

$(document).ready(function() {

    function loadMorePosts( callback ){
        $.get($('.more a').attr('href'), function(data) { 
                $('#container').append($(data)); 
                if ( typeof(callback) == "function" ){ callback(); }
        })
    }
    loadMorePosts();

    var $footer = $('footer');
    var opts = {
        offset: '100%'
    };

    $footer.waypoint(function(event, direction) {
                        $footer.waypoint('remove');
                        loadMorePosts( function(){ $footer.waypoint(opts);} );


            }, opts);
});

the function loadMorePosts invokes the method $.get which is a simpler syntax for $.ajax({type:'GET' .. }). It uses the same URL as the link's href attribute has. In my example the href attribute points to "more_posts.php".

When my demo loads, the content is completely empty, so I go ahead and fetch the first post I want to show. Then I tell waypoint to listen on the footer - and whenever the footer is close by, I go and get more posts.

There's a tricky part where I do $footer.waypoint('remove') and pass a callback to loadMorePosts which binds waypoint to footer once again. This is just a technicality - waypoint need you to remove the trigger while you fetch more HTML, other your page might act funny..

This is more or less that..

I tried to make this as simple as possible, but it's a huge issue to cover in one answer. So let me know if I can do more to clear things up.

guy mograbi
  • 22,955
  • 13
  • 75
  • 115
  • Sorry I don't have access to server scripts but the waypoint solution is what we went with and it's working well. Thanks very much for all the answers. – Tara Irvine Aug 29 '12 at 15:12