【问题标题】:Set height of a Div by Offset was jerky/lagging按偏移量设置的 Div 高度不稳定/滞后
【发布时间】:2021-02-14 12:49:27
【问题描述】:

在我的网络应用程序中,我尝试在滚动事件上设置 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>

component.ts:

export class ProfilComponent implements OnInit {

  constructor() {
  }

  ngOnInit(): void {

  }


  @HostListener('window:scroll', ['$event'])
  scrollHandler(event) {
    console.log(window.pageYOffset)
    const offset = window.pageYOffset
    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");
    }
  }

组件.scss:

.header{
  position: fixed;
  display: flex;
  flex-direction: column-reverse;

  background-image: url("../../../../../assets/exempleCover.png");
  background-size: cover;
  background-repeat: no-repeat;

  width: 100%;
  height: 151px;
  top: 59px;
  background-color: red;
}

......

.panel{
  position: relative;
  top: 0;
  width: auto;
  margin-top: 146px;
  z-index: 2;
}

the scroll laggy

【问题讨论】:

    标签: javascript angular animation scroll offset


    【解决方案1】:

    非常感谢阿米尔,

    不幸的是,当我尝试使用 renderer2 时出现错误:

    我有 zone-evergreen.js:171 Uncaught TypeError: Cannot read property 'setAttribute' of undefined cuz this.panel is undefined.

    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");
        // }
      }
    

    【讨论】:

    • 您好,如果您使用回调中的上下文 (this),您需要在订阅时绑定它,例如 window.addEventListener('scroll', this.scrollHandler.bind(this)); 或者更好的选择是将 scrollHandler 更改为关闭 @987654324 的 lambda 函数@ 语境。请查看我的更新答案。
    【解决方案2】:

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

    最简单的方法是:

    NgZone 注入到您的组件中:

    constuctor(private readonly ngZone: NgZone) { }
    

    通过本机浏览器api订阅ngOnInit()中的滚动事件(您也可以使用Renderer2):

    this.zone.runOutsideAngular(() => {
      window.addEventListener('scroll', this.scrollHandler);
    });
    

    别忘了取消订阅ngOnDestroy()中的事件:

    window.removeEventListener('scroll', this.scrollHandler);
    

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

    scrollHandler = (event) => {
      console.log(window.pageYOffset);
      const offset = window.pageYOffset;
      ...
    }
    

    我在编辑器中写了代码,所以可能有一些错字。

    【讨论】:

    • hks 非常 Amir,不幸的是,当我尝试使用 renderer2 时出现错误:我有 zone-evergreen.js:171 Uncaught TypeError: Cannot read property 'setAttribute' of undefined cuz this.panel未定义。
    猜你喜欢
    • 2023-03-12
    • 1970-01-01
    • 2017-07-21
    • 1970-01-01
    • 1970-01-01
    • 2011-01-19
    • 2014-02-05
    • 1970-01-01
    • 2013-01-15
    相关资源
    最近更新 更多