【问题标题】:IntersectionObserver is not defined error on server side. Intersection Observer with angular universal(Server side rendering)IntersectionObserver 在服务器端未定义错误。带角度通用的交叉点观察器(服务器端渲染)
【发布时间】:2020-04-02 06:27:13
【问题描述】:

我有一个有角度的通用应用程序(服务器端渲染)。 我正在使用 IntersectionObserver 延迟加载图像,它工作正常。虽然它在服务器端日志(pm2 server-error.log)上给了我这个错误。

ERROR ReferenceError: IntersectionObserver is not defined
    at LazyLoadDirective.lazyLoadImage (/home/ubuntu/dist/server/main.js:13160:21)
    at LazyLoadDirective.ngAfterViewInit (/home/ubuntu/dist/server/main.js:13154:33)
    at callProviderLifecycles (/home/ubuntu/dist/server/main.js:52384:18)
    at callElementProvidersLifecycles (/home/ubuntu/dist/server/main.js:52349:13)
    at callLifecycleHooksChildrenFirst (/home/ubuntu/dist/server/main.js:52331:29)
    at checkAndUpdateView (/home/ubuntu/dist/server/main.js:63214:5)
    at callViewAction (/home/ubuntu/dist/server/main.js:63570:21)
    at execComponentViewsAction (/home/ubuntu/dist/server/main.js:63498:13)
    at checkAndUpdateView (/home/ubuntu/dist/server/main.js:63211:5)
    at callViewAction (/home/ubuntu/dist/server/main.js:63570:21)

我的理解是因为 IntersectionObserver 是客户端的东西,因为它对 DOM 元素进行操作。

但是在服务器端看到上述错误有点烦人,所以我想纠正这个问题,因为我通过将 PLATEFORM_ID 注入到我的延迟加载指令中来借助 isPlateformBrowser 函数。它对我来说仍然可以正常工作,我没有看到任何服务器端错误日志。

这是我的 LazyLoadDirective 代码

export class LazyLoadDirective implements AfterViewInit{

    @HostBinding('attr.src') srcAtr = null;
    @Input() src: string;

    constructor(private el: ElementRef, @Inject(PLATFORM_ID) private plateformId : Object) {}

    //putting check for isplateformbrowser.
    ngAfterViewInit(){
        if(isPlatformBrowser(this.plateformId)){
        this.canLazyLoad ? this.lazyLoadImage() : this.loadImage();
        }
    }

    private canLazyLoad(){
        return window && 'IntersectionObserver' in window;
    }

    private lazyLoadImage(){
        const obs = new IntersectionObserver(entries =>{
            entries.forEach(({ isIntersecting })=>{
                console.log("intersecting value isIntersecting",isIntersecting);
                if(isIntersecting){
                    this.loadImage();
                    obs.unobserve(this.el.nativeElement);
                }

            });
        });

        obs.observe(this.el.nativeElement);
    }

    private loadImage(){
        this.srcAtr = this.src;
    }
}

由于这对我来说是新事物,如果有人可以为这个问题提出更好的解决方案,这对我真的很有帮助,而且我在不同的平台上看到了一些帖子,IntersectionObserver 不可靠。请帮助我了解这可能会导致麻烦的情况,任何指向博客文章的链接或任何类型的帮助对我来说都足够了。 谢谢。

【问题讨论】:

  • 为什么需要更好的解决方案?我认为这是一个足够好的。至于 IntersectionObserver,它应该几乎可以在任何地方工作 (caniuse.com/#search=IntersectionObserver)
  • 好的,感谢您的回复和链接,大卫,尽管这已在我的代码中使用并且工作正常(因为我对可靠性有疑问)。

标签: angular8 angular-universal intersection-observer


【解决方案1】:

太棒了!!!我在该指令上添加了一个 '@HostBinding('class') elementVisibilityClass: string' 以根据可见性状态在目标元素上添加一个 CSS 类。

@HostBinding('class') elementVisibilityClass: string;
...
private _callback = (entries: any) => {
    entries.forEach((entry: any) => {
      this.elementVisibilityClass = entry.isIntersecting ? 'visible' : 'hidden';
    });
}

【讨论】:

    猜你喜欢
    • 2020-07-08
    • 1970-01-01
    • 2017-05-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-30
    • 1970-01-01
    相关资源
    最近更新 更多