angular2-virtual-scroll
Advanced tools
Comparing version 0.0.6 to 0.0.7
# v0.0.4 | ||
# v0.0.7 | ||
* Bug fix: [Multi-column scroll is broken in the demo #6](https://github.com/rintoj/angular2-virtual-scroll/issues/6) | ||
# v0.0.6 | ||
* Updating documentation | ||
# v0.0.5 | ||
* Merging pull request: [Completely define ngOnChanges function signature #2](https://github.com/rintoj/angular2-virtual-scroll/pull/2) | ||
@@ -5,0 +13,0 @@ |
@@ -1,2 +0,2 @@ | ||
import { Renderer, OnDestroy, OnChanges, ElementRef, EventEmitter, ModuleWithProviders, SimpleChanges } from '@angular/core'; | ||
import { ElementRef, EventEmitter, ModuleWithProviders, OnChanges, OnDestroy, OnInit, Renderer, SimpleChanges } from '@angular/core'; | ||
export interface IndexUpdateEvent { | ||
@@ -6,3 +6,3 @@ start?: number; | ||
} | ||
export declare class VirtualScrollComponent implements OnDestroy, OnChanges { | ||
export declare class VirtualScrollComponent implements OnInit, OnDestroy, OnChanges { | ||
private element; | ||
@@ -25,2 +25,3 @@ private renderer; | ||
constructor(element: ElementRef, renderer: Renderer); | ||
ngOnInit(): void; | ||
ngOnChanges(changes: SimpleChanges): void; | ||
@@ -30,2 +31,4 @@ ngOnDestroy(): void; | ||
scrollInto(item: any): void; | ||
private countItemsPerRow(); | ||
private calculateDimensions(); | ||
private calculateItems(); | ||
@@ -32,0 +35,0 @@ } |
@@ -18,9 +18,11 @@ "use strict"; | ||
this.items = []; | ||
this.scrollbarWidth = 10; | ||
this.scrollbarHeight = 0; | ||
this.update = new core_1.EventEmitter(); | ||
this.indexUpdate = new core_1.EventEmitter(); | ||
this.startupLoop = true; | ||
} | ||
VirtualScrollComponent.prototype.ngOnInit = function () { | ||
this.onScrollListener = this.renderer.listen(this.element.nativeElement, 'scroll', this.refresh.bind(this)); | ||
} | ||
this.scrollbarWidth = 0; // this.element.nativeElement.offsetWidth - this.element.nativeElement.clientWidth; | ||
this.scrollbarHeight = 0; // this.element.nativeElement.offsetHeight - this.element.nativeElement.clientHeight; | ||
}; | ||
VirtualScrollComponent.prototype.ngOnChanges = function (changes) { | ||
@@ -41,21 +43,21 @@ this.previousStart = undefined; | ||
return; | ||
var el = this.element.nativeElement; | ||
var content = this.contentElementRef.nativeElement; | ||
var viewWidth = el.clientWidth; | ||
var viewHeight = el.clientHeight; | ||
var contentDimensions = content.children[0] ? content.children[0].getBoundingClientRect() : { | ||
width: viewWidth, | ||
height: viewHeight | ||
}; | ||
var childWidth = contentDimensions.width; | ||
var childHeight = contentDimensions.height; | ||
var itemsPerRow = Math.max(1, Math.floor(viewWidth / childWidth)); | ||
var itemsPerCol = Math.max(1, Math.floor(viewHeight / childHeight)); | ||
el.scrollTop = Math.floor(index / itemsPerRow) * childHeight - Math.max(0, (itemsPerCol - 1)) * childHeight; | ||
var d = this.calculateDimensions(); | ||
this.element.nativeElement.scrollTop = Math.floor(index / d.itemsPerRow) * | ||
d.childHeight - Math.max(0, (d.itemsPerCol - 1)) * d.childHeight; | ||
this.refresh(); | ||
}; | ||
VirtualScrollComponent.prototype.calculateItems = function () { | ||
VirtualScrollComponent.prototype.countItemsPerRow = function () { | ||
var offsetTop; | ||
var itemsPerRow; | ||
var children = this.contentElementRef.nativeElement.children; | ||
for (itemsPerRow = 0; itemsPerRow < children.length; itemsPerRow++) { | ||
if (offsetTop != undefined && offsetTop !== children[itemsPerRow].offsetTop) | ||
break; | ||
offsetTop = children[itemsPerRow].offsetTop; | ||
} | ||
return itemsPerRow; | ||
}; | ||
VirtualScrollComponent.prototype.calculateDimensions = function () { | ||
var el = this.element.nativeElement; | ||
var content = this.contentElementRef.nativeElement; | ||
var scrollTop = el.scrollTop; | ||
var items = this.items || []; | ||
@@ -74,9 +76,31 @@ var itemCount = items.length; | ||
var childHeight = this.childHeight || contentDimensions.height; | ||
var itemsPerRow = Math.max(1, Math.floor(viewWidth / childWidth)); | ||
var itemsPerRow = Math.max(1, this.countItemsPerRow()); | ||
var itemsPerRowByCalc = Math.max(1, Math.floor(viewWidth / childWidth)); | ||
var itemsPerCol = Math.max(1, Math.floor(viewHeight / childHeight)); | ||
this.scrollHeight = childHeight * itemCount / itemsPerRow; | ||
var start = Math.floor(scrollTop / this.scrollHeight * itemCount / itemsPerRow) * itemsPerRow; | ||
var end = Math.min(itemCount, Math.ceil(scrollTop / this.scrollHeight * itemCount / itemsPerRow) * itemsPerRow + itemsPerRow * (itemsPerCol + 1)); | ||
; | ||
this.topPadding = childHeight * Math.ceil(start / itemsPerRow); | ||
if (itemsPerCol === 1 && Math.floor(el.scrollTop / this.scrollHeight * itemCount) + itemsPerRowByCalc >= itemCount) { | ||
itemsPerRow = itemsPerRowByCalc; | ||
} | ||
return { | ||
itemCount: itemCount, | ||
viewWidth: viewWidth, | ||
viewHeight: viewHeight, | ||
childWidth: childWidth, | ||
childHeight: childHeight, | ||
itemsPerRow: itemsPerRow, | ||
itemsPerCol: itemsPerCol, | ||
itemsPerRowByCalc: itemsPerRowByCalc | ||
}; | ||
}; | ||
VirtualScrollComponent.prototype.calculateItems = function () { | ||
var el = this.element.nativeElement; | ||
var d = this.calculateDimensions(); | ||
var items = this.items || []; | ||
this.scrollHeight = d.childHeight * d.itemCount / d.itemsPerRow; | ||
if (this.element.nativeElement.scrollTop > this.scrollHeight) { | ||
this.element.nativeElement.scrollTop = this.scrollHeight; | ||
} | ||
var start = Math.floor(el.scrollTop / this.scrollHeight * d.itemCount / d.itemsPerRow) * d.itemsPerRow; | ||
var end = Math.min(d.itemCount, Math.ceil(el.scrollTop / this.scrollHeight * d.itemCount / d.itemsPerRow) * d.itemsPerRow + | ||
d.itemsPerRow * (d.itemsPerCol + 1)); | ||
this.topPadding = d.childHeight * Math.ceil(start / d.itemsPerRow); | ||
if (start !== this.previousStart || end !== this.previousEnd) { | ||
@@ -83,0 +107,0 @@ this.update.emit(items.slice(start, end)); |
{ | ||
"name": "angular2-virtual-scroll", | ||
"version": "0.0.6", | ||
"version": "0.0.7", | ||
"description": "Angular 2 module for virtual -infinite- list. Supports multi-column", | ||
@@ -8,9 +8,10 @@ "main": "dist/virtual-scroll.js", | ||
"scripts": { | ||
"tsc": "node_modules/typescript/bin/tsc", | ||
"build": "npm run tsc --", | ||
"tslint": "tslint", | ||
"lint": "tslint src/**/*.ts", | ||
"watch": "npm run tsc -- -w", | ||
"prepublish": "npm run build", | ||
"start": "npm run watch", | ||
"test": "npm test" | ||
"test": "npm test", | ||
"tsc": "node_modules/typescript/bin/tsc", | ||
"tslint": "tslint", | ||
"watch": "npm run tsc -- -w" | ||
}, | ||
@@ -17,0 +18,0 @@ "repository": { |
@@ -8,13 +8,11 @@ | ||
This module does not render every record in the list at once; instead a small subset of records just enough to fill the viewport are rendered and reused as the user scrolls. Thus displaying an infinitely growing list of items in a viewport of size just about a couple rows in an efficient way is made possible. | ||
This module displays a small subset of records just enough to fill the viewport and uses the same DOM elements as the user scrolls. | ||
This method is effective because the number of DOM elements are always constant and tiny irrespective of the size of the list. Thus virtual scroll can display infinitely growing list of items in an efficient way. | ||
* Angular 2 compatible module | ||
* Supports multi-column | ||
* Angular 2 compatible module | ||
* Easy to use apis | ||
* OpenSource and available in GitHub | ||
* OpenSource and available in [GitHub](https://github.com/rintoj/angular2-virtual-scroll) | ||
### Important Note | ||
Items must have fixed height and width for this module to work perfectly. However if your list happen to have items with variable width and height, set `childWidth` and `childHeight` to the smallest possible values manually to make this work. | ||
## Demo | ||
@@ -111,2 +109,58 @@ | ||
Child component is not a necessity if your item is simple enough. See below. | ||
``` | ||
<virtual-scroll [items]="items" (update)="viewPortItems = $event"> | ||
<div *ngFor="let item of viewPortItems">{{item?.name}}</div> | ||
</virtual-scroll> | ||
``` | ||
## Items with variable size | ||
Items must have fixed height and width for this module to work perfectly. However if your list happen to have items with variable width and height, set inputs `childWidth` and `childHeight` to the smallest possible values to make this work. | ||
``` | ||
<virtual-scroll [items]="items" | ||
[childWidth]="80" | ||
[childHeight]="30" | ||
(update)="viewPortItems = $event"> | ||
<list-item *ngFor="let item of viewPortItems" [item]="item"> | ||
</list-item> | ||
</virtual-scroll> | ||
``` | ||
## If container size change | ||
If virtual scroll is used within a dropdown or collapsible menu, virtual scroll needs to know when the container size change. Use `refresh()` function after container is resized (include time for animation as well). | ||
``` | ||
import { Component, ViewChild } from '@angular/core'; | ||
import { VirtualScrollComponent } from 'angular2-virtual-scroll'; | ||
@Component({ | ||
selector: 'rj-list', | ||
template: ` | ||
<virtual-scroll [items]="items" (update)="scrollList = $event"> | ||
<div *ngFor="let item of scrollList; let i = index"> {{i}}: {{item}} </div> | ||
</virtual-scroll> | ||
` | ||
}) | ||
export class ListComponent { | ||
protected items = ['Item1', 'Item2', 'Item3']; | ||
@ViewChild(VirtualScrollComponent) | ||
private virtualScroll: VirtualScrollComponent; | ||
// call this function after resize + animation end | ||
afterResize() { | ||
this.virtualScroll.refresh(); | ||
} | ||
} | ||
``` | ||
This will be deprecated once [Resize Observer](https://wicg.github.io/ResizeObserver/) is fully implemented. | ||
## Contributing | ||
@@ -152,2 +206,2 @@ Contributions are very welcome! Just send a pull request. Feel free to contact me or checkout my [GitHub](https://github.com/rintoj) page. | ||
THE SOFTWARE. | ||
``` | ||
``` |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
29202
421
205