2

Let's imagine I want to make a social media application. I make a div to hold all my posts. When I start the application, I only query as many requests as will fit on the viewport. I append them as divs themselves. When the user scrolls to the point that they can see n more posts, n more posts are queried and appended to the div.

Or another, an application that you can infinitely scroll and generates random numbers for each div, using similar logic as above.

How can I implement this? I have no idea where to start, but right now what I think I might be able to get away with adding a scroll event. Here's some psuedocode of how that might look, but I'm not sure if I can do something like this (or if it's valid logic, because it's late at night):

unsigned lastY
document.addEventListener('scroll', () => {
  // check if there is space to add more elements
  if ((lastY - postsDiv.sizeY) != 0) { // yes, there is space to add more elements
    // how many can we?
    unsigned toAdd = 
      // (I am very, very unsure if this is correct)
      floor(lastY - postsDiv.sizeY) * postsDiv.lengthInYOfEachElement;
  }
  lastY = window.scrollY
})

Is this even a good approach?

2 Answers 2

5

You can do this easily with the Intersection Observer (IO)

Basically you set up your structure like this:

let options = {
  rootMargin: '0px',
  threshold: 0.9
};
target = document.querySelector('#js-load-more');

observer = new IntersectionObserver(entries => {
  var entry = entries[0];
  if (entry.isIntersecting) {
    console.log('You reached the bottom of the list!');
    appendMorePosts();
  }
}, options);
observer.observe(target);

appendMorePosts = function() {
  const post = document.createElement('div');
  post.classList.add('post');
  post.innerHTML = 'blabla';
  document.querySelector('.post-container').insertBefore(post,document.querySelector('#js-load-more') );
}
.post {
  height: 400px;
  background: linear-gradient(to bottom, hotpink, cyan)
}
<div class="post-container">
<div class="post"> blabla </div> <!-- this is one "post" with images, text, .. -->
<div class="post"> blabla </div>
<div class="post"> blabla </div>
<div id="js-load-more"></div> <!-- just an empty div, to check if you should load more --> 
</div>

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for your answer; I'll look into InteractionObserver as well.
I upvoted the other answer and accepted this one because InteractionObserver looks to be faster in a quick test.
2

You can use element's scrollTop property to check for amount of height scrolled. When this amount gets past a certain percentage of element's visible scroll height, you can add your posts to the element.
In the example below, new numbers are added when user scrolls 90% (0.9) of the height.

let n = 50;
let i = 0;
let cont = document.querySelector(".container");

function generateNumbers(ini) {
  for (var i = ini; i <= n + ini; i++) {
    let span = document.createElement("span");
    span.innerText = i;
    cont.appendChild(span);
  }
}
generateNumbers(i);

cont.addEventListener("scroll", () => {
  if (cont.scrollTop >= (cont.scrollHeight - cont.clientHeight) * 0.9) {
    i = n + 1;
    n += 50;
    generateNumbers(i);
  }
});
.container {
  display: flex;
  flex-direction: column;
  height: 200px;
  overflow: scroll;
}
<div class="container">
</div>

3 Comments

Thanks, this looks like one way to approach it that'd work.
Although in your example if i drag the scrollbar to the bottom of the page then scroll down, it starts generating numbers from a couple hundred behind; why is that?
@gsb Might be some logic error. But you get the idea right?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.