From 7068a5eda6be3df65593df840de4fa15f60b296b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=8D=A1=E8=89=B2?= Date: Tue, 12 Feb 2019 10:12:16 +0800 Subject: [PATCH] fix(module:affix): fix should reset placeholder size when trigger resize event (#2835) * fix(module:affix): fix should reset placeholder size when trigger resize event - close #2818 * chore: fix test --- components/affix/affix.spec.ts | 56 ++++++++++++++------- components/affix/nz-affix.component.html | 2 +- components/affix/nz-affix.component.ts | 63 ++++++++++++++++-------- components/anchor/anchor.spec.ts | 4 +- 4 files changed, 83 insertions(+), 42 deletions(-) diff --git a/components/affix/affix.spec.ts b/components/affix/affix.spec.ts index 6606e04b70f..29f015f63d9 100644 --- a/components/affix/affix.spec.ts +++ b/components/affix/affix.spec.ts @@ -148,6 +148,44 @@ describe('affix', () => { })); }); + describe('resize', () => { + it('should be reset placeholder size', fakeAsync(() => { + const offsetTop = 150; + context.newOffset = offsetTop; + setupInitialState({ offsetTop: offsetTop + 1 }); + const offsetWidthSpy = spyOnProperty(componentObject.elementRef(), 'offsetWidth', 'get'); + emitScroll(window, 2); + expect(componentObject.elementRef().style.width).toBe(`${width}px`); + componentObject.offsetYTo(componentObject.elementRef(), offsetTop + 2); + tick(20); + fixture.detectChanges(); + offsetWidthSpy.and.returnValue(100); + componentObject.emitEvent(window, new Event('resize')); + tick(20); + fixture.detectChanges(); + + expect(componentObject.elementRef().style.width).toBe(`100px`); + + discardPeriodicTasks(); + })); + + it('should be reset placeholder size when container becomes greater', fakeAsync(() => { + const target = componentObject.target(); + const clientHeightSpy = spyOnProperty(target, 'clientHeight', 'get'); + context.fakeTarget = target; + context.newOffsetBottom = 10; + clientHeightSpy.and.returnValue(10); + setupInitialState(); + emitScroll(target, 11); + clientHeightSpy.and.returnValue(100); + componentObject.emitEvent(target, new Event('resize')); + tick(20); + fixture.detectChanges(); + expect(componentObject.elementRef().style.width).toBe(`${componentObject.elementRef().offsetWidth}px`); + discardPeriodicTasks(); + })); + }); + describe('[nzOffsetTop]', () => { const offsetTop = 150; const componentOffset = 160; @@ -329,24 +367,6 @@ describe('affix', () => { })); }); - it('should adjust placeholder width when resize', fakeAsync(() => { - const offsetTop = 150; - context.newOffset = offsetTop; - setupInitialState({ offsetTop: offsetTop + 1 }); - emitScroll(window, 2); - expect(componentObject.elementRef().style.width).toBe(`${width}px`); - componentObject.offsetYTo(componentObject.elementRef(), offsetTop + 2); - tick(20); - fixture.detectChanges(); - componentObject.emitEvent(window, new Event('resize')); - tick(20); - fixture.detectChanges(); - - expect(componentObject.elementRef().style.width).toBe(``); - - discardPeriodicTasks(); - })); - class NzAffixPageObject { offsets: { [key: string]: Offset }; scrolls: { [key: string]: Scroll }; diff --git a/components/affix/nz-affix.component.html b/components/affix/nz-affix.component.html index 7dfef7db131..fccd5c8c4db 100644 --- a/components/affix/nz-affix.component.html +++ b/components/affix/nz-affix.component.html @@ -1,3 +1,3 @@ -
+
\ No newline at end of file diff --git a/components/affix/nz-affix.component.ts b/components/affix/nz-affix.component.ts index 4b579cf62cc..22a13dba504 100644 --- a/components/affix/nz-affix.component.ts +++ b/components/affix/nz-affix.component.ts @@ -37,7 +37,7 @@ export class NzAffixComponent implements OnInit, OnDestroy { this.clearEventListeners(); this._target = typeof value === 'string' ? this.doc.querySelector(value) : value || window; this.setTargetEventListeners(); - this.updatePosition({}); + this.updatePosition({} as Event); } @Input() @@ -46,6 +46,7 @@ export class NzAffixComponent implements OnInit, OnDestroy { return; } this._offsetTop = toNumber(value, null); + this.updatePosition({} as Event); } get nzOffsetTop(): number { @@ -58,17 +59,19 @@ export class NzAffixComponent implements OnInit, OnDestroy { return; } this._offsetBottom = toNumber(value, null); + this.updatePosition({} as Event); } @Output() readonly nzChange: EventEmitter = new EventEmitter(); // tslint:disable-next-line:no-any - constructor(private scrollSrv: NzScrollService, private _el: ElementRef, @Inject(DOCUMENT) private doc: any, private cd: ChangeDetectorRef) { + constructor(_el: ElementRef, private scrollSrv: NzScrollService, @Inject(DOCUMENT) private doc: any, private cd: ChangeDetectorRef) { + this.placeholderNode = _el.nativeElement; } - private timeout; - private events = [ + private timeout: number; + private readonly events = [ 'resize', 'scroll', 'touchstart', @@ -77,10 +80,12 @@ export class NzAffixComponent implements OnInit, OnDestroy { 'pageshow', 'load' ]; - private affixStyle; - private placeholderStyle; - - @ViewChild('wrap') private wrap: ElementRef; + @ViewChild('fixedEl') private fixedEl: ElementRef; + // tslint:disable-next-line:no-any + private affixStyle: any; + // tslint:disable-next-line:no-any + private placeholderStyle: any; + private placeholderNode: HTMLElement; private _target: Element | Window = window; @@ -91,7 +96,7 @@ export class NzAffixComponent implements OnInit, OnDestroy { ngOnInit(): void { this.timeout = setTimeout(() => { this.setTargetEventListeners(); - this.updatePosition({}); + this.updatePosition({} as Event); }); } @@ -166,7 +171,7 @@ export class NzAffixComponent implements OnInit, OnDestroy { } const fixed = !!affixStyle; - const wrapEl = this.wrap.nativeElement as HTMLElement; + const wrapEl = this.fixedEl.nativeElement as HTMLElement; wrapEl.style.cssText = this.genStyle(affixStyle); this.affixStyle = affixStyle; const cls = 'ant-affix'; @@ -186,22 +191,34 @@ export class NzAffixComponent implements OnInit, OnDestroy { if (shallowEqual(placeholderStyle, originalPlaceholderStyle)) { return; } - (this._el.nativeElement as HTMLElement).style.cssText = this.genStyle(placeholderStyle); + this.placeholderNode.style.cssText = this.genStyle(placeholderStyle); this.placeholderStyle = placeholderStyle; } + private syncPlaceholderStyle(e: Event): void { + if (!this.affixStyle) { + return ; + } + this.placeholderNode.style.cssText = ''; + const widthObj = { width: this.placeholderNode.offsetWidth }; + this.setAffixStyle(e, { + ...this.affixStyle, + ...widthObj + }); + this.setPlaceholderStyle(widthObj); + } + @throttleByAnimationFrameDecorator() - // tslint:disable-next-line:no-any - updatePosition(e: any): void { + updatePosition(e: Event): void { const targetNode = this._target; // Backwards support let offsetTop = this.nzOffsetTop; const scrollTop = this.scrollSrv.getScroll(targetNode, true); - const affixNode = this._el.nativeElement as HTMLElement; - const elemOffset = this.getOffset(affixNode, targetNode); + const elemOffset = this.getOffset(this.placeholderNode, targetNode); + const fixedNode = this.fixedEl.nativeElement as HTMLElement; const elemSize = { - width : affixNode.offsetWidth, - height: affixNode.offsetHeight + width : fixedNode.offsetWidth, + height: fixedNode.offsetHeight }; const offsetMode = { top : false, @@ -218,7 +235,7 @@ export class NzAffixComponent implements OnInit, OnDestroy { const targetRect = this.getTargetRect(targetNode); const targetInnerHeight = (targetNode as Window).innerHeight || (targetNode as HTMLElement).clientHeight; - if (scrollTop > elemOffset.top - (offsetTop as number) && offsetMode.top) { + if (scrollTop >= elemOffset.top - (offsetTop as number) && offsetMode.top) { const width = elemOffset.width; const top = targetRect.top + (offsetTop as number); this.setAffixStyle(e, { @@ -233,7 +250,7 @@ export class NzAffixComponent implements OnInit, OnDestroy { height: elemSize.height }); } else if ( - scrollTop < elemOffset.top + elemSize.height + (this._offsetBottom as number) - targetInnerHeight && + scrollTop <= elemOffset.top + elemSize.height + (this._offsetBottom as number) - targetInnerHeight && offsetMode.bottom ) { const targetBottomOffet = targetNode === window ? 0 : (window.innerHeight - targetRect.bottom); @@ -249,12 +266,16 @@ export class NzAffixComponent implements OnInit, OnDestroy { height: elemOffset.height }); } else { - if (e.type === 'resize' && this.affixStyle && this.affixStyle.position === 'fixed' && affixNode.offsetWidth) { - this.setAffixStyle(e, { ...this.affixStyle, width: affixNode.offsetWidth }); + if (e.type === 'resize' && this.affixStyle && this.affixStyle.position === 'fixed' && this.placeholderNode.offsetWidth) { + this.setAffixStyle(e, { ...this.affixStyle, width: this.placeholderNode.offsetWidth }); } else { this.setAffixStyle(e, null); } this.setPlaceholderStyle(null); } + + if (e.type === 'resize') { + this.syncPlaceholderStyle(e); + } } } diff --git a/components/anchor/anchor.spec.ts b/components/anchor/anchor.spec.ts index 85f6335f557..124860d5307 100644 --- a/components/anchor/anchor.spec.ts +++ b/components/anchor/anchor.spec.ts @@ -211,12 +211,12 @@ describe('anchor', () => { expect(el).not.toBeNull(); return el.nativeElement as HTMLElement; } - to(href: string = '#何时使用'): this { + to(href: string = '#basic'): this { this.getEl(`nz-affix [href="${href}"]`).click(); fixture.detectChanges(); return this; } - scrollTo(href: string = '#何时使用'): this { + scrollTo(href: string = '#basic'): this { const toNode = dl.query(By.css(href)); (toNode.nativeElement as HTMLElement).scrollIntoView(); fixture.detectChanges();