/ember-simple-infinite-scroller

:scroll: Simple infinite scroll component for Ember apps

Primary LanguageJavaScriptMIT LicenseMIT

@zestia/ember-simple-infinite-scroller

This Ember addon provides a simple component that fires an action whenever it is scrolled to the bottom. Allowing you to load more data. It is not coupled to Ember-Data like some other infinite scrolling implementations.

Installation

ember install @zestia/ember-simple-infinite-scroller

Demo

https://zestia.github.io/ember-simple-infinite-scroller/

Example

<InfiniteScroller @onLoadMore={{this.loadMore}} as |scroller|>
  {{#each things as |thing|}}
    ...
  {{/each}}
  {{if scroller.isLoading "Please wait..."}}
</InfiniteScroller>

Notes

  • Does not use jQuery ✔︎
  • Ember Data Friendly ✔︎
  • Supports use with FastBoot ✔︎

Configuration

Argument Description Default
onLoadMore Action to perform when the bottom is scrolled into view null
selector Monitors the scrolling of a specific child element, e.g. selector=".foo-bar" null
useDocument Monitors the document scroll position rather than the element's scroll position. false
leeway Percentage distance away from the bottom "0%"
scrollDebounce Milliseconds delay used to check if the bottom has been reached 100 ms

Yielded API

The component will yield a hash that provides:

Property Description
isLoading True when the promise for more data has not resolved yet
isScrollable True when scroll element is overflowing
error The caught error from the last attempt to load more
loadMore Action for manually loading more

Element vs Document scroll

Either make your component scrollable:

.my-element {
  max-height: 300px;
  overflow-y: auto;
}

OR

Set @useDocument={{true}} if your component is not scrollable.

Performance

Please read: TryGhost/Ghost#7934

You may need to add this to app/app.js

customEvents: {
  touchstart: null,
  touchmove: null,
  touchend: null,
  touchcancel: null
}

Other scenarios

If your scrollable element is displaying 10 things, but they don't cause the element to overflow, then the user won't ever be able to load more - because they won't be able to scroll and therefore the onLoadMore action will never fire.

To account for this, you can display a button for manually loading more...

<InfiniteScroller @onLoadMore={{this.loadMore}} as |scroller|>
  {{#each this.things as |thing|}}
    ...
  {{/each}}

  {{#if this.hasMoreThings}}
    {{#if scroller.isScrollable}}
      Loading more...
    {{else}}
      <button {{on "click" scroller.loadMore}}>Load more</button>
    {{/if}}
  {{/if}}
</InfiniteScroller>