fix(aio): make `ScrollSpy` respond quicker to `scroll` events
Fixes ##17220
This commit is contained in:
parent
3a121a621f
commit
bfdd3398f6
|
@ -300,6 +300,7 @@ describe('ScrollSpyService', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('window resize events', () => {
|
describe('window resize events', () => {
|
||||||
|
const RESIZE_EVENT_DELAY = 300;
|
||||||
let onResizeSpy: jasmine.Spy;
|
let onResizeSpy: jasmine.Spy;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
@ -317,7 +318,7 @@ describe('ScrollSpyService', () => {
|
||||||
window.dispatchEvent(new Event('resize'));
|
window.dispatchEvent(new Event('resize'));
|
||||||
expect(onResizeSpy).not.toHaveBeenCalled();
|
expect(onResizeSpy).not.toHaveBeenCalled();
|
||||||
|
|
||||||
tick(300);
|
tick(RESIZE_EVENT_DELAY);
|
||||||
expect(onResizeSpy).toHaveBeenCalled();
|
expect(onResizeSpy).toHaveBeenCalled();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
@ -327,58 +328,59 @@ describe('ScrollSpyService', () => {
|
||||||
onResizeSpy.calls.reset();
|
onResizeSpy.calls.reset();
|
||||||
|
|
||||||
window.dispatchEvent(new Event('resize'));
|
window.dispatchEvent(new Event('resize'));
|
||||||
tick(300);
|
tick(RESIZE_EVENT_DELAY);
|
||||||
expect(onResizeSpy).toHaveBeenCalled();
|
expect(onResizeSpy).toHaveBeenCalled();
|
||||||
|
|
||||||
info1.unspy();
|
info1.unspy();
|
||||||
onResizeSpy.calls.reset();
|
onResizeSpy.calls.reset();
|
||||||
|
|
||||||
window.dispatchEvent(new Event('resize'));
|
window.dispatchEvent(new Event('resize'));
|
||||||
tick(300);
|
tick(RESIZE_EVENT_DELAY);
|
||||||
expect(onResizeSpy).toHaveBeenCalled();
|
expect(onResizeSpy).toHaveBeenCalled();
|
||||||
|
|
||||||
info2.unspy();
|
info2.unspy();
|
||||||
onResizeSpy.calls.reset();
|
onResizeSpy.calls.reset();
|
||||||
|
|
||||||
window.dispatchEvent(new Event('resize'));
|
window.dispatchEvent(new Event('resize'));
|
||||||
tick(300);
|
tick(RESIZE_EVENT_DELAY);
|
||||||
expect(onResizeSpy).not.toHaveBeenCalled();
|
expect(onResizeSpy).not.toHaveBeenCalled();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should only fire every 300ms', fakeAsync(() => {
|
it(`should only fire every ${RESIZE_EVENT_DELAY}ms`, fakeAsync(() => {
|
||||||
scrollSpyService.spyOn([]);
|
scrollSpyService.spyOn([]);
|
||||||
onResizeSpy.calls.reset();
|
onResizeSpy.calls.reset();
|
||||||
|
|
||||||
window.dispatchEvent(new Event('resize'));
|
window.dispatchEvent(new Event('resize'));
|
||||||
tick(100);
|
tick(RESIZE_EVENT_DELAY - 2);
|
||||||
expect(onResizeSpy).not.toHaveBeenCalled();
|
expect(onResizeSpy).not.toHaveBeenCalled();
|
||||||
|
|
||||||
window.dispatchEvent(new Event('resize'));
|
window.dispatchEvent(new Event('resize'));
|
||||||
tick(100);
|
tick(1);
|
||||||
expect(onResizeSpy).not.toHaveBeenCalled();
|
expect(onResizeSpy).not.toHaveBeenCalled();
|
||||||
|
|
||||||
window.dispatchEvent(new Event('resize'));
|
window.dispatchEvent(new Event('resize'));
|
||||||
tick(100);
|
tick(1);
|
||||||
expect(onResizeSpy).toHaveBeenCalledTimes(1);
|
expect(onResizeSpy).toHaveBeenCalledTimes(1);
|
||||||
|
|
||||||
onResizeSpy.calls.reset();
|
onResizeSpy.calls.reset();
|
||||||
tick(150);
|
tick(RESIZE_EVENT_DELAY / 2);
|
||||||
|
|
||||||
window.dispatchEvent(new Event('resize'));
|
window.dispatchEvent(new Event('resize'));
|
||||||
tick(100);
|
tick(RESIZE_EVENT_DELAY - 2);
|
||||||
expect(onResizeSpy).not.toHaveBeenCalled();
|
expect(onResizeSpy).not.toHaveBeenCalled();
|
||||||
|
|
||||||
window.dispatchEvent(new Event('resize'));
|
window.dispatchEvent(new Event('resize'));
|
||||||
tick(100);
|
tick(1);
|
||||||
expect(onResizeSpy).not.toHaveBeenCalled();
|
expect(onResizeSpy).not.toHaveBeenCalled();
|
||||||
|
|
||||||
window.dispatchEvent(new Event('resize'));
|
window.dispatchEvent(new Event('resize'));
|
||||||
tick(100);
|
tick(1);
|
||||||
expect(onResizeSpy).toHaveBeenCalledTimes(1);
|
expect(onResizeSpy).toHaveBeenCalledTimes(1);
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('window scroll events', () => {
|
describe('window scroll events', () => {
|
||||||
|
const SCROLL_EVENT_DELAY = 10;
|
||||||
let onScrollSpy: jasmine.Spy;
|
let onScrollSpy: jasmine.Spy;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
@ -395,7 +397,7 @@ describe('ScrollSpyService', () => {
|
||||||
window.dispatchEvent(new Event('scroll'));
|
window.dispatchEvent(new Event('scroll'));
|
||||||
expect(onScrollSpy).not.toHaveBeenCalled();
|
expect(onScrollSpy).not.toHaveBeenCalled();
|
||||||
|
|
||||||
tick(300);
|
tick(SCROLL_EVENT_DELAY);
|
||||||
expect(onScrollSpy).toHaveBeenCalled();
|
expect(onScrollSpy).toHaveBeenCalled();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
@ -404,52 +406,52 @@ describe('ScrollSpyService', () => {
|
||||||
const info2 = scrollSpyService.spyOn([]);
|
const info2 = scrollSpyService.spyOn([]);
|
||||||
|
|
||||||
window.dispatchEvent(new Event('scroll'));
|
window.dispatchEvent(new Event('scroll'));
|
||||||
tick(300);
|
tick(SCROLL_EVENT_DELAY);
|
||||||
expect(onScrollSpy).toHaveBeenCalled();
|
expect(onScrollSpy).toHaveBeenCalled();
|
||||||
|
|
||||||
info1.unspy();
|
info1.unspy();
|
||||||
onScrollSpy.calls.reset();
|
onScrollSpy.calls.reset();
|
||||||
|
|
||||||
window.dispatchEvent(new Event('scroll'));
|
window.dispatchEvent(new Event('scroll'));
|
||||||
tick(300);
|
tick(SCROLL_EVENT_DELAY);
|
||||||
expect(onScrollSpy).toHaveBeenCalled();
|
expect(onScrollSpy).toHaveBeenCalled();
|
||||||
|
|
||||||
info2.unspy();
|
info2.unspy();
|
||||||
onScrollSpy.calls.reset();
|
onScrollSpy.calls.reset();
|
||||||
|
|
||||||
window.dispatchEvent(new Event('scroll'));
|
window.dispatchEvent(new Event('scroll'));
|
||||||
tick(300);
|
tick(SCROLL_EVENT_DELAY);
|
||||||
expect(onScrollSpy).not.toHaveBeenCalled();
|
expect(onScrollSpy).not.toHaveBeenCalled();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should only fire every 300ms', fakeAsync(() => {
|
it(`should only fire every ${SCROLL_EVENT_DELAY}ms`, fakeAsync(() => {
|
||||||
scrollSpyService.spyOn([]);
|
scrollSpyService.spyOn([]);
|
||||||
|
|
||||||
window.dispatchEvent(new Event('scroll'));
|
window.dispatchEvent(new Event('scroll'));
|
||||||
tick(100);
|
tick(SCROLL_EVENT_DELAY - 2);
|
||||||
expect(onScrollSpy).not.toHaveBeenCalled();
|
expect(onScrollSpy).not.toHaveBeenCalled();
|
||||||
|
|
||||||
window.dispatchEvent(new Event('scroll'));
|
window.dispatchEvent(new Event('scroll'));
|
||||||
tick(100);
|
tick(1);
|
||||||
expect(onScrollSpy).not.toHaveBeenCalled();
|
expect(onScrollSpy).not.toHaveBeenCalled();
|
||||||
|
|
||||||
window.dispatchEvent(new Event('scroll'));
|
window.dispatchEvent(new Event('scroll'));
|
||||||
tick(100);
|
tick(1);
|
||||||
expect(onScrollSpy).toHaveBeenCalledTimes(1);
|
expect(onScrollSpy).toHaveBeenCalledTimes(1);
|
||||||
|
|
||||||
onScrollSpy.calls.reset();
|
onScrollSpy.calls.reset();
|
||||||
tick(150);
|
tick(SCROLL_EVENT_DELAY / 2);
|
||||||
|
|
||||||
window.dispatchEvent(new Event('scroll'));
|
window.dispatchEvent(new Event('scroll'));
|
||||||
tick(100);
|
tick(SCROLL_EVENT_DELAY - 2);
|
||||||
expect(onScrollSpy).not.toHaveBeenCalled();
|
expect(onScrollSpy).not.toHaveBeenCalled();
|
||||||
|
|
||||||
window.dispatchEvent(new Event('scroll'));
|
window.dispatchEvent(new Event('scroll'));
|
||||||
tick(100);
|
tick(1);
|
||||||
expect(onScrollSpy).not.toHaveBeenCalled();
|
expect(onScrollSpy).not.toHaveBeenCalled();
|
||||||
|
|
||||||
window.dispatchEvent(new Event('scroll'));
|
window.dispatchEvent(new Event('scroll'));
|
||||||
tick(100);
|
tick(1);
|
||||||
expect(onScrollSpy).toHaveBeenCalledTimes(1);
|
expect(onScrollSpy).toHaveBeenCalledTimes(1);
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
|
|
@ -124,7 +124,7 @@ export class ScrollSpyService {
|
||||||
private spiedElementGroups: ScrollSpiedElementGroup[] = [];
|
private spiedElementGroups: ScrollSpiedElementGroup[] = [];
|
||||||
private onStopListening = new Subject();
|
private onStopListening = new Subject();
|
||||||
private resizeEvents = Observable.fromEvent(window, 'resize').auditTime(300).takeUntil(this.onStopListening);
|
private resizeEvents = Observable.fromEvent(window, 'resize').auditTime(300).takeUntil(this.onStopListening);
|
||||||
private scrollEvents = Observable.fromEvent(window, 'scroll').auditTime(300).takeUntil(this.onStopListening);
|
private scrollEvents = Observable.fromEvent(window, 'scroll').auditTime(10).takeUntil(this.onStopListening);
|
||||||
private lastContentHeight: number;
|
private lastContentHeight: number;
|
||||||
private lastMaxScrollTop: number;
|
private lastMaxScrollTop: number;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue