Ember Infinite

Infinite scroll based on discourse

by mgrassotti

HTML

<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/normalize/2.1.0/normalize.css">
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.3.1/css/bootstrap.css">
<script src="http://builds.emberjs.com.s3.amazonaws.com/handlebars-1.0.0-rc.3.js"></script>
<script src="http://builds.emberjs.com.s3.amazonaws.com/ember-latest.js"></script>
<script src="http://builds.emberjs.com.s3.amazonaws.com/ember-data-latest.js"></script>
<script type="text/x-handlebars">
    {{outlet}}
  </script>

  <script type="text/x-handlebars" id="post">
    <tr><td>
      {{#linkTo 'post' this}}
        <img src="http://www.placehold.it/20?text=hi"/>
        {{title}} <small class="muted">id: {{id}} </small>{{/linkTo}}
    </td></tr>
  </script>

<script type="text/x-handlebars" id="posts">
    <div class="container-fluid">
      <div class="row-fluid">
        <div class="span12">
          <table class="table">
            <thead>
              <tr><th>All Posts (up to {{limit}})</th></tr>
            </thead>
            {{each limittedContent itemViewClass="App.PostView"}}
          </table>
          {{view 'App.LoadMoreView'}}
        </div>
      </div>
    </div>
  </script>

CSS

/* Put your CSS here */
html, body { margin: 20px; }
.active { font-weight: bold; }

JavaScript

Ember.subscribe('render', {
  before: function(name, start, payload){
    return start
  },
  after: function(name, end, payload, start){
    var duration = Math.round(end - start)
    console.log('rendered', payload.template || '', payload.object, 'took', duration, 'ms')
  }
})

$.fn.isOnScreen = function(){
     
    var win = $(window);
     
    var viewport = {
        top : win.scrollTop(),
        left : win.scrollLeft()
    };
    viewport.right = viewport.left + win.width();
    viewport.bottom = viewport.top + win.height();

    var bounds = this.offset();
    bounds.right = bounds.left + this.outerWidth();
    bounds.bottom = bounds.top + this.outerHeight();

    return (!(viewport.right < bounds.left || viewport.left > bounds.right || viewport.bottom < bounds.top || viewport.top > bounds.bottom));
     
};

App = Ember.Application.create({});

App.Scrolling = Em.Mixin.create({

  /**
    Begin watching for scroll events. By default they will be called at max every 100ms.
    call with {debounce: N} for a diff time

    @method bindScrolling
  */
  bindScrolling: function(opts) {
    var onScroll,
      _this = this;

    opts = opts || {debounce: 100};

    if (opts.debounce) {
      onScroll = App.debounce(function() { return _this.scrolled(); }, 100);
    } else {
      onScroll = function(){ 
          return _this.scrolled(); 
      };
    }
    $(document).bind('touchmove', onScroll);
    $(window).bind('scroll', onScroll);
  },

  /**
    Begin watching for scroll events. They will be called at max every 100ms.

    @method unbindScrolling
  */
  unbindScrolling: function() {
    console.log('unbinding things...');
    $(window).unbind('scroll');
    $(document).unbind('touchmove');
  }

});

/**
  Debounce a Javascript function. This means if it's called many times in a time limit it
  should only be executed once.

  @method debounce
  @module Discourse
  @param {function} func The function to debounce
  @param {Number} wait how long to...