typescript - Angular 6:TypeError:无法读取 null 的属性 'scrollIntoView'
我正在尝试在 Angular 6 中测试 scrollIntoView(),但是遇到了这个错误 --> TypeError: Cannot read property 'scrollIntoView' of null
规格 :
beforeEach(() => {
fixture = TestBed.createComponent(BusinessInfoComponent);
component = fixture.componentInstance;
component.ngOnInit();
spyOn(document.getElementById('info-banner'), 'scrollIntoView').and.callThrough();
expect(document.getElementById('info-banner').scrollIntoView).toHaveBeenCalled();
expect(document.getElementById('info-banner')).not.toBeDefined();
fixture.detectChanges();
});
ts :
ngOnInit() {
document.getElementById('info-banner').scrollIntoView();
}
答案#1
document.getElementById('info-banner').scrollIntoView(); 应该放在 ngAfterViewInit() 生命周期钩子中。
基本上,任何 DOM 引用都应该放入那个钩子中。当 ngOnInit() 被执行时,DOM 还不存在,因此会出现错误。
答案#2
我尝试了之前的所有答案,但没有一个对我有效。我想出了一个解决方法:
⚠️⚠️ 警告 ⚠️⚠️:不推荐在企业应用中使用此代码。问题在于 myTarget 从 @ViewChild 变为已定义的时间不一定总是少于 50 毫秒,因此滚动可能不会 100% 执行。不过就性能而言,我认为这不是大问题。
话虽如此,到目前为止,这在我的应用中100%的情况下都有效,所以对于小型爱好/学校/大学项目来说,这是一个不错的变通方法。在我的应用中,等待总是少于3毫秒。你可以在你的应用中取消注释被注释掉的那一行,以查看你的组件需要多长时间。
async ngAfterViewInit() {
let timesThat1MSWasWaited = 0;
while (this.myTarget === undefined) {
await new Promise(r => setTimeout(r, 1));
if (timesThat1MSWasWaited > 50) {
console.error('FatalException: Waited too long for highlighted song to appear in DOM.');
return;
}
timesThat1MSWasWaited++;
}
// console.debug('Needed to wait at least ' + timesThat1MSWasWaited + 'ms for myTarget to appear.');
this.myTarget.nativeElement.scrollIntoView({
behavior: 'smooth',
block: 'center',
});
}
}
