@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: https://github.com/TryGhost/Ghost/issues/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>