virtual scroll for scrolling grids
This commit is contained in:
parent
9aea9c3635
commit
40f519afd6
@ -84,6 +84,8 @@ import { CircleButtonComponent } from './components/buttons/circle-button/circle
|
||||
import { ChevronButtonComponent } from './components/buttons/chevron-button/chevron-button.component';
|
||||
import { DictionaryListingScreenComponent } from './screens/admin/dictionary-listing-screen/dictionary-listing-screen.component';
|
||||
import { CustomTooltipModule } from './common/red-tooltip/custom-tooltip.module';
|
||||
import { ScrollingModule } from '@angular/cdk/scrolling';
|
||||
import { VirtualScrollComponent } from './utils/virtual-scroll/virtual-scroll.component';
|
||||
|
||||
export function HttpLoaderFactory(httpClient: HttpClient) {
|
||||
return new TranslateHttpLoader(httpClient, '/assets/i18n/', '.json');
|
||||
@ -135,7 +137,8 @@ export function HttpLoaderFactory(httpClient: HttpClient) {
|
||||
UserButtonComponent,
|
||||
CircleButtonComponent,
|
||||
ChevronButtonComponent,
|
||||
DictionaryListingScreenComponent
|
||||
DictionaryListingScreenComponent,
|
||||
VirtualScrollComponent
|
||||
],
|
||||
imports: [
|
||||
BrowserModule,
|
||||
|
||||
@ -152,6 +152,8 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<redaction-virtual-scroll></redaction-virtual-scroll>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
59
apps/red-ui/src/app/utils/sync-scroll.ts
Normal file
59
apps/red-ui/src/app/utils/sync-scroll.ts
Normal file
@ -0,0 +1,59 @@
|
||||
export function syncScroll(elements: HTMLElement[]) {
|
||||
// clearing existing listeners
|
||||
for (const element of elements) {
|
||||
element.removeEventListener('scroll', (<any>element).scrollSync);
|
||||
}
|
||||
|
||||
// setting-up the new listeners
|
||||
for (let idx = 0; idx < elements.length; ) {
|
||||
const loopElement: any = elements[idx++];
|
||||
|
||||
loopElement.eX = loopElement.eY = 0;
|
||||
|
||||
((el) => {
|
||||
el['addEventListener'](
|
||||
'scroll',
|
||||
(el.scrollSync = () => {
|
||||
let scrollX = el['scrollLeft'];
|
||||
let scrollY = el['scrollTop'];
|
||||
|
||||
const xRate = scrollX / (el['scrollWidth'] - el['clientWidth']);
|
||||
const yRate = scrollY / (el['scrollHeight'] - el['clientHeight']);
|
||||
|
||||
const updateX = scrollX !== el.eX;
|
||||
const updateY = scrollY !== el.eY;
|
||||
|
||||
let otherEl,
|
||||
i = 0;
|
||||
|
||||
el.eX = scrollX;
|
||||
el.eY = scrollY;
|
||||
|
||||
for (; i < elements.length; ) {
|
||||
otherEl = elements[i++];
|
||||
if (otherEl !== el) {
|
||||
if (
|
||||
updateX &&
|
||||
Math.round(
|
||||
otherEl['scrollLeft'] - (scrollX = otherEl.eX = Math.round(xRate * (otherEl['scrollWidth'] - otherEl['clientWidth'])))
|
||||
)
|
||||
) {
|
||||
otherEl['scrollLeft'] = scrollX;
|
||||
}
|
||||
|
||||
if (
|
||||
updateY &&
|
||||
Math.round(
|
||||
otherEl['scrollTop'] - (scrollY = otherEl.eY = Math.round(yRate * (otherEl['scrollHeight'] - otherEl['clientHeight'])))
|
||||
)
|
||||
) {
|
||||
otherEl['scrollTop'] = scrollY;
|
||||
}
|
||||
}
|
||||
}
|
||||
}),
|
||||
0
|
||||
);
|
||||
})(loopElement);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
<div class="virtual-scroll" #scrollElement>
|
||||
<div class="virtual" [style.height]="height + 'px'"></div>
|
||||
</div>
|
||||
@ -0,0 +1,15 @@
|
||||
.virtual-scroll {
|
||||
// TODO fix this - pass information as input or such
|
||||
display: none;
|
||||
position: fixed;
|
||||
width: 10px;
|
||||
right: 480px;
|
||||
bottom: 0;
|
||||
z-index: 100;
|
||||
top: 191px;
|
||||
overflow: auto;
|
||||
|
||||
.virtual {
|
||||
height: 2000px;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,26 @@
|
||||
import { AfterViewInit, Component, ElementRef, Input, ViewChild } from '@angular/core';
|
||||
import { syncScroll } from '../sync-scroll';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-virtual-scroll',
|
||||
templateUrl: './virtual-scroll.component.html',
|
||||
styleUrls: ['./virtual-scroll.component.scss']
|
||||
})
|
||||
export class VirtualScrollComponent implements AfterViewInit {
|
||||
@Input() targetQuerySelector = '.red-content';
|
||||
@ViewChild('scrollElement')
|
||||
scrollElement: ElementRef;
|
||||
content: HTMLElement;
|
||||
height: number;
|
||||
factor: number;
|
||||
|
||||
constructor() {}
|
||||
|
||||
ngAfterViewInit(): void {
|
||||
this.content = document.querySelector(this.targetQuerySelector);
|
||||
this.factor = this.content.clientHeight / this.scrollElement.nativeElement.clientHeight;
|
||||
this.height = Math.round(this.content.scrollHeight / this.factor);
|
||||
console.log(this.factor, this.height);
|
||||
syncScroll([this.scrollElement.nativeElement, this.content]);
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user