Skip to content

Instantly share code, notes, and snippets.

Created January 21, 2016 05:45

Revisions

  1. @invalid-email-address Anonymous created this gist Jan 21, 2016.
    365 changes: 365 additions & 0 deletions index.html
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,365 @@
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="utf-8">
    <title>Ember Starter Kit</title>
    <link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/normalize/3.0.1/normalize.css">
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
    <script src="http://builds.emberjs.com/tags/v1.13.5/ember-template-compiler.js"></script>
    <script src="http://builds.emberjs.com/tags/v1.13.5/ember.debug.js"></script>
    <style id="jsbin-css">
    /* Put your CSS here */
    html, body {
    margin: 20px;
    }

    h1, h2 {
    font-weight: normal;
    }

    #container {
    width: 300px;
    height: 200px;
    outline: 1px solid black;
    overflow: scroll;
    position: relative;
    }

    #scroller {
    position: absolute;
    background-color: blue;
    width: 100%;
    }

    .item {
    position: absolute;
    outline: 1px solid white;
    height: 40px;
    width: 100%;
    line-height: 40px;
    padding-left: 10px;
    color: white;
    background-color: green;
    }
    </style>
    </head>
    <body>

    <script type="text/x-handlebars">
    <h1>Scroll Scroll</h1>
    {{outlet}}
    </script>

    <script type="text/x-handlebars" id="components/x-virtual-list">
    <div id="container">
    <div id="scroller" style={{scrollerStyle}}>
    {{#each visibleItems as |item|}}
    <div class="item" style={{item.style}}>{{item.name}}</div>
    {{/each}}
    </div>
    </div>
    <div>
    <p>scroll offset: {{scrollOffset}}</p>
    <p>visible elements: {{visibleItems.length}}</p>
    <p>start offset: {{startOffset}}</p>
    <p>end offset: {{endOffset}}</p>
    <p>start index: {{startIndex}}</p>
    <p>end index: {{endIndex}}</p>
    </div>
    </script>

    <script type="text/x-handlebars" data-template-name="index">
    {{x-virtual-list items=model}}
    </script>

    <script id="jsbin-javascript">
    App = Ember.Application.create();

    App.Router.map(function() {
    // put your routes here
    });

    App.IndexRoute = Ember.Route.extend({
    model: function() {
    var people = [
    'Bill',
    'Zach',
    'Seung',
    'Kapil',
    'Tom',
    'Ren',
    'George',
    'Ed',
    'Ben',
    'Curtis',
    'Allie',
    'Tao',
    'David',
    'Gian',
    'Clifton',
    'Richard',
    'Max',
    'Tony',
    'Kiran',
    'Mike',
    'Brian',
    'Joe',
    'Matt',
    'Alex',
    'Jeremy',
    'Travis'
    ];
    var items = [];
    for (var i = 0; i < 1000; i++) {
    var person = people[Math.floor(Math.random() * people.length)];
    items.push((i+1) + ". " + person);
    }
    return items;
    }
    });

    App.XVirtualListComponent = Ember.Component.extend({
    rowHeight: 40,
    scrollOffset: 0,
    containerHeight: 0,

    visibleItems: function() {
    var rowHeight = this.get('rowHeight');
    var startIndex = this.get('startIndex');
    var endIndex = this.get('endIndex');
    return this.get('items').slice(startIndex, endIndex).map(function(name, i) {
    var index = i + startIndex;
    var top = (rowHeight * index);
    return {
    name: name,
    style: new Ember.Handlebars.SafeString("top: " + top + "px;")
    };
    });
    }.property('items', 'rowHeight', 'startIndex', 'endIndex'),

    startOffset: function() {
    return Math.abs(this.get('scrollOffset')) / this.get('rowHeight');
    }.property('scrollOffset', 'containerHeight', 'rowHeight'),

    endOffset: function() {
    return (Math.abs(this.get('scrollOffset')) + this.getWithDefault('containerHeight', 0)) / this.get('rowHeight');
    }.property('scrollOffset', 'containerHeight', 'rowHeight'),

    startIndex: function() {
    return Math.floor(this.get('startOffset'));
    }.property('startOffset'),

    endIndex: function() {
    return Math.ceil(this.get('endOffset'));
    }.property('endOffset'),

    scrollerStyle: function() {
    var height = this.get('items.length') * this.get('rowHeight');
    var style = "height: " + height + "px";
    return new Ember.Handlebars.SafeString(style);
    }.property('items.length', 'rowHeight'),

    hookupScroll: function() {
    var view = this;
    $('#container').bind('scroll', function() {
    Ember.run.once(view, function() {
    var containerOffset = $('#container').offset().top;
    var scrollerOffset = $('#scroller').offset().top;
    var scrollOffset = scrollerOffset - containerOffset;
    view.set('scrollOffset', scrollOffset);
    });
    });
    }.on('didInsertElement'),

    readySetGo: function() {
    Ember.run.later(this, function() {
    this.set('containerHeight', Ember.$('#container').height());
    });
    }.on('didInsertElement'),

    });
    </script>

    <script id="jsbin-source-html" type="text/html"><!DOCTYPE html>
    <html>
    <head>
    <meta charset="utf-8">
    <title>Ember Starter Kit</title>
    <link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/normalize/3.0.1/normalize.css">
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"><\/script>
    <script src="http://builds.emberjs.com/tags/v1.13.5/ember-template-compiler.js"><\/script>
    <script src="http://builds.emberjs.com/tags/v1.13.5/ember.debug.js"><\/script>
    </head>
    <body>

    <script type="text/x-handlebars">
    <h1>Scroll Scroll</h1>
    {{outlet}}
    <\/script>

    <script type="text/x-handlebars" id="components/x-virtual-list">
    <div id="container">
    <div id="scroller" style={{scrollerStyle}}>
    {{#each visibleItems as |item|}}
    <div class="item" style={{item.style}}>{{item.name}}</div>
    {{/each}}
    </div>
    </div>
    <div>
    <p>scroll offset: {{scrollOffset}}</p>
    <p>visible elements: {{visibleItems.length}}</p>
    <p>start offset: {{startOffset}}</p>
    <p>end offset: {{endOffset}}</p>
    <p>start index: {{startIndex}}</p>
    <p>end index: {{endIndex}}</p>
    </div>
    <\/script>

    <script type="text/x-handlebars" data-template-name="index">
    {{x-virtual-list items=model}}
    <\/script>

    </body>
    </html>
    </script>

    <script id="jsbin-source-css" type="text/css">/* Put your CSS here */
    html, body {
    margin: 20px;
    }

    h1, h2 {
    font-weight: normal;
    }

    #container {
    width: 300px;
    height: 200px;
    outline: 1px solid black;
    overflow: scroll;
    position: relative;
    }

    #scroller {
    position: absolute;
    background-color: blue;
    width: 100%;
    }

    .item {
    position: absolute;
    outline: 1px solid white;
    height: 40px;
    width: 100%;
    line-height: 40px;
    padding-left: 10px;
    color: white;
    background-color: green;
    }</script>

    <script id="jsbin-source-javascript" type="text/javascript">App = Ember.Application.create();

    App.Router.map(function() {
    // put your routes here
    });

    App.IndexRoute = Ember.Route.extend({
    model: function() {
    var people = [
    'Bill',
    'Zach',
    'Seung',
    'Kapil',
    'Tom',
    'Ren',
    'George',
    'Ed',
    'Ben',
    'Curtis',
    'Allie',
    'Tao',
    'David',
    'Gian',
    'Clifton',
    'Richard',
    'Max',
    'Tony',
    'Kiran',
    'Mike',
    'Brian',
    'Joe',
    'Matt',
    'Alex',
    'Jeremy',
    'Travis'
    ];
    var items = [];
    for (var i = 0; i < 1000; i++) {
    var person = people[Math.floor(Math.random() * people.length)];
    items.push((i+1) + ". " + person);
    }
    return items;
    }
    });

    App.XVirtualListComponent = Ember.Component.extend({
    rowHeight: 40,
    scrollOffset: 0,
    containerHeight: 0,

    visibleItems: function() {
    var rowHeight = this.get('rowHeight');
    var startIndex = this.get('startIndex');
    var endIndex = this.get('endIndex');
    return this.get('items').slice(startIndex, endIndex).map(function(name, i) {
    var index = i + startIndex;
    var top = (rowHeight * index);
    return {
    name: name,
    style: new Ember.Handlebars.SafeString("top: " + top + "px;")
    };
    });
    }.property('items', 'rowHeight', 'startIndex', 'endIndex'),

    startOffset: function() {
    return Math.abs(this.get('scrollOffset')) / this.get('rowHeight');
    }.property('scrollOffset', 'containerHeight', 'rowHeight'),

    endOffset: function() {
    return (Math.abs(this.get('scrollOffset')) + this.getWithDefault('containerHeight', 0)) / this.get('rowHeight');
    }.property('scrollOffset', 'containerHeight', 'rowHeight'),

    startIndex: function() {
    return Math.floor(this.get('startOffset'));
    }.property('startOffset'),

    endIndex: function() {
    return Math.ceil(this.get('endOffset'));
    }.property('endOffset'),

    scrollerStyle: function() {
    var height = this.get('items.length') * this.get('rowHeight');
    var style = "height: " + height + "px";
    return new Ember.Handlebars.SafeString(style);
    }.property('items.length', 'rowHeight'),

    hookupScroll: function() {
    var view = this;
    $('#container').bind('scroll', function() {
    Ember.run.once(view, function() {
    var containerOffset = $('#container').offset().top;
    var scrollerOffset = $('#scroller').offset().top;
    var scrollOffset = scrollerOffset - containerOffset;
    view.set('scrollOffset', scrollOffset);
    });
    });
    }.on('didInsertElement'),

    readySetGo: function() {
    Ember.run.later(this, function() {
    this.set('containerHeight', Ember.$('#container').height());
    });
    }.on('didInsertElement'),

    });</script></body>
    </html>
    33 changes: 33 additions & 0 deletions jsbin.nibosocevi.css
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,33 @@
    /* Put your CSS here */
    html, body {
    margin: 20px;
    }

    h1, h2 {
    font-weight: normal;
    }

    #container {
    width: 300px;
    height: 200px;
    outline: 1px solid black;
    overflow: scroll;
    position: relative;
    }

    #scroller {
    position: absolute;
    background-color: blue;
    width: 100%;
    }

    .item {
    position: absolute;
    outline: 1px solid white;
    height: 40px;
    width: 100%;
    line-height: 40px;
    padding-left: 10px;
    color: white;
    background-color: green;
    }
    105 changes: 105 additions & 0 deletions jsbin.nibosocevi.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,105 @@
    App = Ember.Application.create();

    App.Router.map(function() {
    // put your routes here
    });

    App.IndexRoute = Ember.Route.extend({
    model: function() {
    var people = [
    'Bill',
    'Zach',
    'Seung',
    'Kapil',
    'Tom',
    'Ren',
    'George',
    'Ed',
    'Ben',
    'Curtis',
    'Allie',
    'Tao',
    'David',
    'Gian',
    'Clifton',
    'Richard',
    'Max',
    'Tony',
    'Kiran',
    'Mike',
    'Brian',
    'Joe',
    'Matt',
    'Alex',
    'Jeremy',
    'Travis'
    ];
    var items = [];
    for (var i = 0; i < 1000; i++) {
    var person = people[Math.floor(Math.random() * people.length)];
    items.push((i+1) + ". " + person);
    }
    return items;
    }
    });

    App.XVirtualListComponent = Ember.Component.extend({
    rowHeight: 40,
    scrollOffset: 0,
    containerHeight: 0,

    visibleItems: function() {
    var rowHeight = this.get('rowHeight');
    var startIndex = this.get('startIndex');
    var endIndex = this.get('endIndex');
    return this.get('items').slice(startIndex, endIndex).map(function(name, i) {
    var index = i + startIndex;
    var top = (rowHeight * index);
    return {
    name: name,
    style: new Ember.Handlebars.SafeString("top: " + top + "px;")
    };
    });
    }.property('items', 'rowHeight', 'startIndex', 'endIndex'),

    startOffset: function() {
    return Math.abs(this.get('scrollOffset')) / this.get('rowHeight');
    }.property('scrollOffset', 'containerHeight', 'rowHeight'),

    endOffset: function() {
    return (Math.abs(this.get('scrollOffset')) + this.getWithDefault('containerHeight', 0)) / this.get('rowHeight');
    }.property('scrollOffset', 'containerHeight', 'rowHeight'),

    startIndex: function() {
    return Math.floor(this.get('startOffset'));
    }.property('startOffset'),

    endIndex: function() {
    return Math.ceil(this.get('endOffset'));
    }.property('endOffset'),

    scrollerStyle: function() {
    var height = this.get('items.length') * this.get('rowHeight');
    var style = "height: " + height + "px";
    return new Ember.Handlebars.SafeString(style);
    }.property('items.length', 'rowHeight'),

    hookupScroll: function() {
    var view = this;
    $('#container').bind('scroll', function() {
    Ember.run.once(view, function() {
    var containerOffset = $('#container').offset().top;
    var scrollerOffset = $('#scroller').offset().top;
    var scrollOffset = scrollerOffset - containerOffset;
    view.set('scrollOffset', scrollOffset);
    });
    });
    }.on('didInsertElement'),

    readySetGo: function() {
    Ember.run.later(this, function() {
    this.set('containerHeight', Ember.$('#container').height());
    });
    }.on('didInsertElement'),

    });