有没有办法使用 HostListener 和 Angular 中的指令来查找用户是否已到达不可滚动 div 的底部?

问题描述 投票:0回答:1

在我的角度应用程序中,我有一个带有柔性显示屏的主布局,高度为 100vh,溢出设置为隐藏。里面是主要内容 div,高度为 100%,溢出设置为滚动。

<router-outlet />
插入到主要内容 div 内。这样做是为了保持布局不变,并且插入其中的任何组件都不必设置任何特定于主布局的 CSS。并且滚动适用于主要内容 div,因此默认情况下任何插入的 HTML 元素都将具有其完整高度。

main-layout.html

<section class="main-container">
  <section>
    <app-sidebar />
  </section>
  
  <section class="content">
    <header>
      <app-header />
    </header>
    
    <main class="inner-layout padding scrollable">
      <router-outlet />
    </main>
  </section>
</section>

main-layout.scss

.main-container {
  display: flex;
}

.content {
  display: flex;
  flex-direction: column;
  margin: auto;
  width: 100%;
  height: 100vh;
  overflow: hidden;
}

.inner-layout {
  &.padding {
    padding: 2.5rem 3rem;
    height: 100%;
  }

  &.scrollable {
    height: 100%;
    overflow: auto;
  }
}

我在主布局内插入了一个组件(通过路由器出口),该组件的 div 文本高度超过 100vh。因此,为主布局生成了一个滚动条(不是带有文本的 div)。

child-component.html


<div> <div> Div top </div> <div style="height: 1500px;"> This div has a lot of text. This div has a height more than 100vh, therefore a scrollbar is generated in the main-layout.html </div> <div> Div bottom </div> </div>
我想知道用户何时到达带有文本的 div 末尾。

我尝试使用一个指令,该指令将 HostListner 与

这个答案中给出的滚动事件一起使用,但问题是滚动事件发生在 main-layout.html 中的内部布局 div 上,而不是发生在带有文本。如果我在内部布局 div 上使用相同的指令,它会起作用,因为滚动条仅针对该 div 出现,但我正在寻找一种方法来查找用户是否已到达没有的特定 div 的末尾滚动条。

detect-end.directive.ts


@Directive({ selector: '[detectEnd]', standalone: true }) export class DetectEndDirective { @Output() scrolled = new EventEmitter<void>(); @HostListener('scroll', ['$event']) onScroll(event: any) { let tracker = event.target; let limit = tracker.scrollHeight - tracker.clientHeight; if (event.target.scrollTop === limit) { alert('end reached'); this.scrolled.emit(); } } }
    
html angular scroll angular2-directives
1个回答
0
投票
看起来计算在计算后给出了十进制值

919.0908813476562

,所以最好使用
>
运算符,除了代码工作正常!

指令

import { Directive, EventEmitter, Output, HostListener } from '@angular/core'; @Directive({ selector: '[detectEnd]', standalone: true, }) export class DetectEndDirective { @Output() scrolled = new EventEmitter<void>(); @HostListener('scroll', ['$event']) onScroll(event: any) { let tracker = event.target; let limit = tracker.scrollHeight - tracker.clientHeight; if (event.target.scrollTop > limit) { // <- changed here! alert('end reached'); this.scrolled.emit(); } } }
布局.html

<section class="main-container"> <section> <app-sidebar /> </section> <section class="content"> <header> <app-header /> </header> <main class="inner-layout padding scrollable" detectEnd (scrolled)="scrolled()"> <router-outlet /> </main> </section> </section>
布局.ts

import { Component } from '@angular/core'; import { RouterOutlet } from '@angular/router'; import { HeaderComponent } from '../header/header.component'; import { SidebarComponent } from '../sidebar/sidebar.component'; import { DetectEndDirective } from '../detect-end.directive'; @Component({ selector: 'app-layout', standalone: true, imports: [ HeaderComponent, SidebarComponent, DetectEndDirective, RouterOutlet, ], templateUrl: './layout.component.html', styleUrl: './layout.component.scss', }) export class LayoutComponent { scrolled() { alert('scrolled to bottom'); } }

Stackblitz 演示

© www.soinside.com 2019 - 2024. All rights reserved.