Infinite Scroll
by rlivsey
HTML
<script src="https://github.com/downloads/emberjs/ember.js/ember-0.9.7.js"></script>
<script type="text/x-handlebars">
<div class="scroll-container">
{{view App.InfiniteScrollView contentBinding="App.items"}}
</div>
</script>
CSS
body {
padding: 10px;
}
.scroll-container {
border: 1px solid #CCC;
height: 200px;
width: 200px;
overflow: auto;
background-color: red;
padding: 30px 0;
}
.scroll-container ol {
}
.scroll-container li {
padding: 5px;
background-color: #FFF;
}
.scroll-container li:nth-of-type(odd) {
background-color: #EEE;
}
JavaScript
App = Ember.Application.create({});
App.ItemView = Ember.View.extend({
template: Ember.Handlebars.compile('item: {{content.text}}'),
});
App.InfiniteScrollView = Ember.CollectionView.extend({
tagName: 'ol',
itemViewClass: 'App.ItemView',
scrollBuffer: 50,
scrolledToBottom: function() {
// store away the last item so we can scroll back to it
this.lastView = this.getPath("childViews.lastObject");
this.lastOffset = this.$().parent().scrollTop();
this.scrollDirection = "down";
// would trigger ajax request to load in data
this.get("content").fetchNextPage();
},
scrolledToTop: function() {
// store away the top item so we can scroll back to it
this.lastView = this.getPath("childViews.firstObject");
this.lastOffset = this.$().parent().scrollTop();
this.scrollDirection = "up";
// would trigger ajax request to load in data
this.get("content").fetchPrevPage();
},
didInsertChildElements: function(view) {
if (this.lastView) {
var position = this.scrollDirection == "up" ? "top" : "bottom";
this.scrollToView(this.lastView, position);
this.lastView = null;
} else {
if (!this.hasSetup) {
this.scrollToTop();
this.hasSetup = true;
}
}
},
// TODO - assumes equal padding top and bottom, figure out by other dimensions
scrollToTop: function() {
var $container = this.$().parent();
var padding = ($container.innerHeight() - $container.height()) / 2;
this.$().parent().scrollTop(padding);
},
scrollToView: function(view, position) {
if (!view) {
return;
}
if (position == "top") {
var itemTop = view.$().position().top;
this.$().parent().scrollTop(this.lastOffset + itemTop);
} else {
...