Issue
I am trying to write some code that will allow me to observe a scrollable list, I want to check whether the first item of the list is visible, if it is do not make the button visible but if the first item is hidden, make the button visible as it will be a 'scroll to top button'.
Do I add the directive to the button or the list? I assume I add it to the button but how do i then check whether the list items are intersected or not?
@Directive({
selector: '[appInview]',
})
export class InviewDirective implements AfterViewInit {
@Input() elementToWatch?: HTMLElement; // Button
private observer?: IntersectionObserver;
constructor(private el: ElementRef) {}
ngAfterViewInit(): void {
this.observer = new IntersectionObserver(
(entries) => {
if (entries[0].isIntersecting === true) {
this.elementToWatch?.setAttribute('hidden', 'true');
} else {
this.elementToWatch?.removeAttribute('hidden');
}
},
{
threshold: 0.75,
}
);
this.observer.observe(this.el.nativeElement as HTMLElement);
}
ngOnDestroy() {
this.observer?.disconnect();
}
}
Solution
Is this the expected output, I attached to an ngFor
and allowed the directive to work only for the first element using first
variable of ngFor
, then the code started working fine!
main ts
import { CommonModule } from '@angular/common';
import { Component } from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';
import 'zone.js';
import { InviewDirective } from './in-view.directive';
@Component({
selector: 'app-root',
standalone: true,
imports: [CommonModule, InviewDirective],
template: `
<h2>Users</h2>
<button #button style="position: fixed; left: 0px;top:0px;">just a button</button>
<ul>
<li *ngFor="let user of users;let first=first" [appInView]="first" [elementToWatch]="button">
<h3>{{user.firstName}} {{user.lastName}}</h3>
<ul>
<li>Age:{{user.age}}</li>
<li>Address - > {{user.address.city}} {{user.address.street}},{{user.address.state}}</li>
</ul>
</li>
</ul>
`,
})
export class App {
users: any[] = [];
constructor() {}
ngOnInit() {
this.users = [
{
firstName: 'Nasir',
lastName: 'Shaik',
age: 28,
address: {
city: 'Nellore',
state: 'AP',
street: 'Jyothi Nager 5th Street',
},
},
{
firstName: 'Asif',
lastName: 'Shaik',
age: 27,
address: {
city: 'Nellore',
state: 'AP',
street: 'vedayapalam 8th street',
},
},
{
firstName: 'Kumar',
lastName: 'Sitty',
age: 28,
address: {
city: 'Nellore',
state: 'AP',
street: 'Chandramouli nagar',
},
},
{
firstName: 'Kumar',
lastName: 'Sitty',
age: 28,
address: {
city: 'Nellore',
state: 'AP',
street: 'Chandramouli nagar',
},
},
{
firstName: 'Kumar',
lastName: 'Sitty',
age: 28,
address: {
city: 'Nellore',
state: 'AP',
street: 'Chandramouli nagar',
},
},
{
firstName: 'Kumar',
lastName: 'Sitty',
age: 28,
address: {
city: 'Nellore',
state: 'AP',
street: 'Chandramouli nagar',
},
},
{
firstName: 'Kumar',
lastName: 'Sitty',
age: 28,
address: {
city: 'Nellore',
state: 'AP',
street: 'Chandramouli nagar',
},
},
{
firstName: 'Kumar',
lastName: 'Sitty',
age: 28,
address: {
city: 'Nellore',
state: 'AP',
street: 'Chandramouli nagar',
},
},
{
firstName: 'Kumar',
lastName: 'Sitty',
age: 28,
address: {
city: 'Nellore',
state: 'AP',
street: 'Chandramouli nagar',
},
},
{
firstName: 'Kumar',
lastName: 'Sitty',
age: 28,
address: {
city: 'Nellore',
state: 'AP',
street: 'Chandramouli nagar',
},
},
{
firstName: 'Kumar',
lastName: 'Sitty',
age: 28,
address: {
city: 'Nellore',
state: 'AP',
street: 'Chandramouli nagar',
},
},
{
firstName: 'Kumar',
lastName: 'Sitty',
age: 28,
address: {
city: 'Nellore',
state: 'AP',
street: 'Chandramouli nagar',
},
},
{
firstName: 'Kumar',
lastName: 'Sitty',
age: 28,
address: {
city: 'Nellore',
state: 'AP',
street: 'Chandramouli nagar',
},
},
{
firstName: 'Kumar',
lastName: 'Sitty',
age: 28,
address: {
city: 'Nellore',
state: 'AP',
street: 'Chandramouli nagar',
},
},
];
this.addUser({
firstName: 'Krishna',
lastName: 'lankha',
age: 26,
address: {
city: 'Tirupathi',
state: 'AP',
street: 'udyagari colony',
},
});
}
addUser(users: any) {
this.users.push(users);
}
}
bootstrapApplication(App);
directive
import { Directive, ElementRef, Input, AfterViewInit } from '@angular/core';
@Directive({
selector: '[appInView]',
standalone: true,
})
export class InviewDirective implements AfterViewInit {
@Input() elementToWatch?: HTMLElement; // Button
@Input() appInView: boolean = false; // Button
private observer?: IntersectionObserver;
constructor(private el: ElementRef) {}
ngAfterViewInit(): void {
if (!this.appInView) return;
this.observer = new IntersectionObserver(
(entries) => {
console.log(entries);
if (entries[0].isIntersecting) {
this.elementToWatch?.setAttribute('hidden', 'true');
} else {
this.elementToWatch?.removeAttribute('hidden');
}
},
{
threshold: 0.75,
}
);
this.observer.observe(this.el.nativeElement as HTMLElement);
}
ngOnDestroy() {
this.observer?.disconnect();
}
}
Answered By - Naren Murali
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.