Javascript 通过偏移量设置的Div高度不稳定/滞后

Javascript 通过偏移量设置的Div高度不稳定/滞后,javascript,angular,animation,scroll,offset,Javascript,Angular,Animation,Scroll,Offset,在我的web应用程序中,我尝试在滚动事件中设置一个div的高度,以产生UI效果和视差, 当我在顶部滚动时,Div变大,当我滚动到底部页面时,Div变小以产生视差效果 我使用了@HostListener('window:scroll',['$event'])来触发滚动,它的工作,但结果在定格时非常不稳定,随机延迟 有人知道为什么会有这么多车吗?或者一个角度库可以通过性能优化实现这一点 component.html: <div id="header" class=&

在我的web应用程序中,我尝试在滚动事件中设置一个div的高度,以产生UI效果和视差, 当我在顶部滚动时,Div变大,当我滚动到底部页面时,Div变小以产生视差效果

我使用了@HostListener('window:scroll',['$event'])来触发滚动,它的工作,但结果在定格时非常不稳定,随机延迟

有人知道为什么会有这么多车吗?或者一个角度库可以通过性能优化实现这一点

component.html:

    <div id="header" class="header" >
      <div class="coverBackgroundGradiantUp">  </div>
        <div class="coverBackgroundGradiantDown">
        </div>
    </div>

<div id="panel" class="panel" (scroll)="scrollHandler($event)">
{...bodypage...}
</div>

当您订阅像angular这样的事件时,会在每次回调执行后(每次触发DOM事件并执行回调时)运行更改检测。您需要在angular zone之外手动订阅DOM事件

最简单的方法是:

NgZone
注入组件:

constuctor(private readonly ngZone: NgZone) { }
通过本机浏览器api订阅
ngOnInit()
中的滚动事件(您也可以使用
Renderer2
):

不要忘记取消订阅
ngondstroy()
中的活动:

scrollHandler
函数更改为lambda格式,以绑定上下文并在将来能够取消订阅:

scrollHandler = (event) => {
  console.log(window.pageYOffset);
  const offset = window.pageYOffset;
  ...
}
我是在编辑器中编写代码的,所以可能会有一些打字错误。

非常感谢阿米尔

不幸的是,当我尝试使用Render2时,出现了一个错误:

我有zone evergreen.js:171未捕获类型错误:无法读取未定义的属性“setAttribute”,因为this.panel未定义

export class ProfilComponent implements OnInit, AfterViewInit {

  ***@ViewChildren('panel') panel: ElementRef;***

  constructor(private readonly ngZone: NgZone, private renderer: Renderer2){ }

  ngOnInit(): void {
    this.ngZone.runOutsideAngular(() => {
      window.addEventListener('scroll', this.scrollHandler);
    });
  }

  ngAfterViewInit() {

    console.log(this.panel);
  }


  scrollHandler(event) {
    **console.log(this.panel)**
    const offset = window.pageYOffset

    **this.renderer.setAttribute(this.panel.nativeElement, "id", "panel")**;



    // if (offset < -1) {
    //   document.getElementById("headerHeight").style.width = String((100 - offset/6)+ "%");
    //
    //   document.getElementById("headerHeight").style.height = String( 151 - offset + "px");
    // } else if (offset < 151) {
    //   document.getElementById("headerHeight").style.height = String( 151 - offset + "px");
    // } else if (offset > 151) {
    //   document.getElementById("headerHeight").style.height = String(0 + "px");
    // }
  }
导出类ProfilComponent实现OnInit,AfterViewInit{
***@ViewChildren(“面板”)面板:ElementRef***
构造函数(私有只读ngZone:ngZone,私有呈现器:Renderer2){}
ngOnInit():void{
此.ngZone.runOutsideAngular(()=>{
window.addEventListener('scroll',this.scrollHandler);
});
}
ngAfterViewInit(){
console.log(这个.panel);
}
scrollHandler(事件){
**console.log(this.panel)**
常量偏移=window.pageYOffset
**this.renderer.setAttribute(this.panel.nativeElement,“id”,“panel”)**;
//如果(偏移量<-1){
//document.getElementById(“headerHeight”).style.width=String((100-offset/6)+“%”);
//
//document.getElementById(“headerHeight”).style.height=String(151-offset+“px”);
//}else if(偏移量<151){
//document.getElementById(“headerHeight”).style.height=String(151-offset+“px”);
//}否则如果(偏移量>151){
//document.getElementById(“headerHeight”).style.height=String(0+“px”);
// }
}

hks非常Amir,不幸的是,当我尝试使用renderer2时,我出现了一个错误:我有zone evergreen.js:171 Uncaught TypeError:无法读取未定义的属性'setAttribute',因为this.panel未定义。您好,如果您使用回调中的上下文(this),则需要在订阅时绑定它,如
window.addEventListener('scroll',this.scrollHandler.bind(this));
或者更好的选择是将
scrollHandler
更改为lambda函数,该函数关闭
此上下文。请查看我的更新答案。
this.zone.runOutsideAngular(() => {
  window.addEventListener('scroll', this.scrollHandler);
});
window.removeEventListener('scroll', this.scrollHandler);
scrollHandler = (event) => {
  console.log(window.pageYOffset);
  const offset = window.pageYOffset;
  ...
}
export class ProfilComponent implements OnInit, AfterViewInit {

  ***@ViewChildren('panel') panel: ElementRef;***

  constructor(private readonly ngZone: NgZone, private renderer: Renderer2){ }

  ngOnInit(): void {
    this.ngZone.runOutsideAngular(() => {
      window.addEventListener('scroll', this.scrollHandler);
    });
  }

  ngAfterViewInit() {

    console.log(this.panel);
  }


  scrollHandler(event) {
    **console.log(this.panel)**
    const offset = window.pageYOffset

    **this.renderer.setAttribute(this.panel.nativeElement, "id", "panel")**;



    // if (offset < -1) {
    //   document.getElementById("headerHeight").style.width = String((100 - offset/6)+ "%");
    //
    //   document.getElementById("headerHeight").style.height = String( 151 - offset + "px");
    // } else if (offset < 151) {
    //   document.getElementById("headerHeight").style.height = String( 151 - offset + "px");
    // } else if (offset > 151) {
    //   document.getElementById("headerHeight").style.height = String(0 + "px");
    // }
  }