16

I was watching Matthew Podwysocki event on https://www.youtube.com/watch?v=zlERo_JMGCw 29:38

Where he explains how they solved scroll on netflix. Where user scroll for more data as previous data gets cleaned up and more adds up (but scroll back shows previous data again).

I wanted to do similar, but I grabbed netflix demo code:

function getRowUpdates(row) {
  var scrolls = Rx.Observable.fromEvent(document, 'scroll');
  var rowVisibilities = 
    scrolls.throttle(50)
      .map(function(scrollEvent) {
        return row.isVisible(scrollEvent.offset);
      })
      .distinctUntilChanged();

  var rowShows = rowrowVisibilities.filter(function(v) {
    return v;
  });
  var rowHides = rowrowVisibilities.filter(function(v) {
    return !v;
  });

  return rowShows
    .flatMap(Rx.Observable.interval(10))
    .flatMap(function() {
      return row.getRowData().takeUntil(rowHides);
    })
    .toArray();
}

But I'm bit confused on how to pass new data or page data according to the scroll here.. Can someone give little explanation on how I can do the following:

  • fetch first list (I can do that)
  • fetch more list as user scroll down (using paging next page)
  • remove previous fetched data from memory, and refetch on request (scroll up).
Dennis Hackethal
  • 13,662
  • 12
  • 66
  • 115
Basit
  • 16,316
  • 31
  • 93
  • 154

1 Answers1

2

Here is how I would do it in general lines. If this seems to give you satisfaction, I'll edit and add more details.

Version 2 : (For first one, see edit changes)

Premises :

  1. The tag containing the dynamic list will be called "the zone".
  2. Each row of the list will be contained in another DIV which can contains anything.
  3. A page is enough rows to cover the zone.
  4. Three javascript "constants" : numberOfLinesOnFirstLoad, numberOfLinesOnPageLoad, numberOfLinesToLoadAfter
  5. JavaScript variables to hold required data : rows[page#], heights[page#], currentPageNumber = 1, maxPageNumber = 0
  6. page# : # is the page number
  7. rows[page#] shall contains a way to get them back from database, not real DOM objects.

Steps / Events :

  1. Add the zone tag.
  2. Load numberOfLinesOnFirstLoad rows.
  3. If total rows height inferior zone height multiplied by three, then load numberOfLinesToLoadAfter rows. Repeat step 3 if rows added, otherwise continue to step 4.
  4. maxPageNumber +=1. Find the next rows that full fills the zone. Add those rows to rows["page" + maxPageNumber] (as an array). Calculate the height of those and add it in heights["page" + maxPageNumber].
  5. Repeat step 4 until no more rows and then continue to step 6.
  6. When scrolling down and page1 (which means last element of rows["page1"]) is not visible, add another below : page4.
  7. maxPageNumber += 1. Load numberOfLinesOnPageLoad rows.
  8. If total new rows height inferior zone height, then numberOfLinesToLoadAfter rows. Repeat step 8 if rows added, otherwise put total new rows height in heights["page" + maxPageNumber] and the new rows as array in rows["page" + maxPageNumber] and continue to the step after entering this one (so either 9 or 11).
  9. Still scrolling down, if page2 is not visible, remove the page1 elements from DOM and adjust scroll position by removing page1.height (heights["page1"]).
  10. Load page 5 (step 7 and 8).
  11. So now, there is page2 to page5 in the zone which page2 and page5 are not visible. If page3 is fully visible, than page4 is not, otherwise a part of page3 and page4 are visible. (Just to indicate possibilities, but not important)
  12. When scrolling up and page2 is starting to be visible (so last element of rows["page2"]), load page1 by using rows["page1"], add page1.height (heights["page1"]) to scroll position and remove page5 from DOM. Here you can either remove it from variables rows && heights and maxPageNumber -= 1, but you can also keep them so that reloading this page is done in one process (so loading a page would imply to check if page definition already exists in those variables).
Master DJon
  • 1,899
  • 2
  • 19
  • 30
  • how can one do it without knowing height of the items or do we just get the height by `$('div').height();`? – Basit Mar 30 '16 at 17:34
  • On load below the screen, knowing the height is not necessary. This implies the first load. So, I considered that pages removed from scrolling down will be the same when scrolling up. And then, yes, just taking the height using something like `$('div page1').height()` will do the job for reloading on scrolling up. – Master DJon Mar 30 '16 at 18:34
  • Just to be clear, here I spoke in terms of fixed height pages (because you wrote by "pages" in your question). Though, in reality it is more unknown height lines that we should talk about and most probably not the whole window but only a part of it, a zone. So at first glance, you load let's say 10 lines in the zone. If those lines height is over or equal 3 times the height of the zone you stop first loading there. Otherwise, you continue loading until you reach this. You shall have variables that you can set as : firstNumberOfRowsToGather, moreNumberOfRowsToGather, pageNumberOfRowsToGather... – Master DJon Mar 30 '16 at 19:27
  • The first and last one are used with the middle one. With the last one, you shall verify that the loaded data gave 1 more "visible" page, which is the height of the zone. If it doesn't than using the "moreNum..." variable to continue loading up to getting the "page height". So when the code is done, tweaking will be required to adjust those variables to get something acceptable for your site. – Master DJon Mar 30 '16 at 19:27
  • How it sounds ? If good, I'll change the answer to reflect that. – Master DJon Mar 30 '16 at 20:20
  • Well i'm showing line by line text items.. text can be huge or very small, if its huge then the line height will be bigger compare to other lines. So I'm confused on how to overcome with such situation where each line height is dynamic. – Basit Mar 30 '16 at 22:07
  • I modified the answer to reflect my comments and yours. Tell me if it is enough clear. Not sure how to be more clear (without writing the whole code), but I can try. – Master DJon Mar 31 '16 at 03:50
  • would that all will be possible using `RxJS` as I posted the code above. seems like it will require to go out of scope – Basit Mar 31 '16 at 12:18
  • I'm about sure you will have to. – Master DJon Mar 31 '16 at 13:24