In my angular application, I have a main layout with a flex display that has a height of 100vh and overflow set to hidden. Inside is the main content div which has a height of 100% and overflow set to scroll. <router-outlet /> is inserted inside the main content div. This is done so that the layout is kept unchanged, and any component inserted inside don't have to set up any CSS specific to the main layout. And the scrolling applies to the main content div so any inserted HTML elements will have their full height by default.
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;
}
}
I have a component inserted inside the main layout (through the router outlet) that has a div with text that has a height more than 100vh. So a scrollbar is generated for the main layout (not the div with the text).
child-component.html
<div>
<div>
Div top
</div>
<div style="min-height: 1500px; border: 5px solid red; display: flex; flex-direction: column; justify-content: space-between">
<h1>
The directive should detect when the user scrolls to the end of this div
</h1>
This div has a lot of text.
<p>This div has a height more than 100vh, therefore a scrollbar is generated in the main-layout.html</p>
<h1>End of div. The directive should detect when the user is here.</h1>
</div>
<div style="min-height: 500px;">
Div bottom
</div>
</div>
I want to know when the user reaches the end of the div with the text.
I tried using a directive that uses HostListner with a scroll event that was given in this answer, but the issue is that the scroll event happens to the inner-layout div in the main-layout.html Not to the div with the text. If I use the same directive on the inner-layout div, it works since the scrollbar appears only for that div, but I'm looking for a way to find if the user has reached the end of a specific div that doesn't have a scrollbar.
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();
}
}
}
Looks like the calculation is giving decimal value
919.0908813476562after calculations(919.0908813476562 === 919 will give you false), so it's better you use the>operator, apart from that the code works fine!directive
layout.html
layout.ts
Stackblitz Demo