Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save karthikeyan-arumugam-1558/ab29f2e5e38b2aba7a6e91843e1c2861 to your computer and use it in GitHub Desktop.
Save karthikeyan-arumugam-1558/ab29f2e5e38b2aba7a6e91843e1c2861 to your computer and use it in GitHub Desktop.
New Twiddle
import Ember from 'ember';
const {
Component,
computed
} = Ember;
export default Component.extend({
attributeBindings: ['style'],
itemCount: computed.alias('items.length'),
viewportHeight: computed(function () {
return this.get('itemCount') * this.get('rowHeight');
}),
startIndex: computed('scrollTop', function () {
let startNode = Math.floor(this.get('scrollTop') / this.get('rowHeight')) - this.get('nodePadding');
startNode = Math.max(0, startNode);
return startNode;
}),
visibleNodeCount: computed('startIndex', function () {
let count = Math.ceil(this.get('rootHeight') / this.get('rowHeight')) + 2 * this.get('nodePadding');
count = Math.min(this.get('itemCount') - this.get('startIndex'), count);
return count;
}),
visibleItems: computed('startIndex', 'visibleNodeCount', function () {
return this.get('items').slice(
this.get('startIndex'),
this.get('startIndex') + this.get('visibleNodeCount')
);
}),
offsetY: computed('startIndex', function () {
return this.get('startIndex') * this.get('rowHeight');
}),
spacerStyle: computed('offsetY', function () {
return `transform: translateY(${this.get('offsetY')}px)`;
}),
viewportStyle: computed(function () {
return `
overflow: hidden;
height: ${this.get('viewportHeight')}px;
position: relative;
`;
}),
style: computed(function () {
return `
overflow: auto;
height: ${this.get('rootHeight')}px;
`;
}),
handleScroll() {
this.set('scrollTop', this.get('element.scrollTop'));
},
init() {
this._super(...arguments);
this.set('scrollTop', 0);
this.set('handleScroll', this.get('handleScroll').bind(this));
},
didInsertElement() {
this._super(...arguments);
this.get('element').addEventListener('scroll', this.get('handleScroll'), { passive: true });
},
willDestroyElement() {
this._super(...arguments);
this.get('element').removeEventListener('scroll', this.get('handleScroll'));
}
})
import Ember from 'ember';
const {
Controller,
computed
} = Ember;
export default Controller.extend({
items: computed(function () {
return new Array(100000)
.fill(null)
.map((item, index) => "Item " + (index + 1));
})
});
.viewport {
background: #fefefe;
overflow-y: auto;
}
.spacer > div {
padding: 0.5rem 0rem;
border: 1px solid #f5f5f5;
}
{{#virtual-scroll
rootHeight=400
rowHeight=30
nodePadding=20
items=items
as |visibleItems|
}}
{{#each visibleItems as |item|}}
<div>{{item}}</div>
{{/each}}
{{/virtual-scroll}}
<div class="viewport" style={{viewportStyle}}>
<div class="spacer" style={{spacerStyle}}>
{{yield visibleItems}}
</div>
</div>
{
"version": "0.17.1",
"EmberENV": {
"FEATURES": {},
"_TEMPLATE_ONLY_GLIMMER_COMPONENTS": false,
"_APPLICATION_TEMPLATE_WRAPPER": true,
"_JQUERY_INTEGRATION": true
},
"options": {
"use_pods": false,
"enable-testing": false
},
"dependencies": {
"jquery": "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.js",
"ember": "2.16.2",
"ember-template-compiler": "2.16.2",
"ember-testing": "2.16.2"
},
"addons": {
"@glimmer/component": "1.0.0"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment