Let's prepare a simple demo now. Where we will use our directive.
The first step is to prepare a list of elements. Then we add the inViewport
directive to the li
element. After that we configure it by setting [inViewportOptions]
. In this case, we set { threshold: [0] }
because we want to change className
of the li
element as soon as it is visible. Finally, we assign the onIntersection($event)
method execution to the (inViewportAction)
output.
/src/app/app.component.html
Copy <ul class="list">
<li class="list-item inactive"
inViewport
[inViewportOptions]="{ threshold: [0] }"
(inViewportAction)="onIntersection($event)"
*ngFor="let item of items;">
<span>{{item}}</span>
</li>
</ul>
The second step is to make our demo look nice.
/src/app/app.component.scss
Copy ul .list {
margin : 0 ;
padding : 24 px ;
display : block ;
list-style : none ;
> li . list-item {
width : 100 % ;
height : 25 vh ;
margin : 0 ;
padding : 0 ;
display : flex ;
justify-content : center ;
align-items : center ;
transition : background-color .25 s ease-in-out , color .25 s ease-in-out ;
& : not(:first-child ) {
margin-top : 12 px ;
}
& .inactive {
background-color : #CCCCCC ;
color : rgba (#000000 , .85) ;
}
& .active {
background-color : #00C853 ;
color : rgba (#FFFFFF , .85) ;
}
> span {
font-weight : 700 ;
}
}
}
The third and final step is to fill an array of items and to prepare the implementation of our onIntersection(): void
method.
/src/app/app.component.ts
Copy import { Component , Renderer2 } from '@angular/core' ;
@ Component ({
selector : 'app-root' ,
templateUrl : './app.component.html' ,
styleUrls : [ './app.component.scss' ]
})
export class AppComponent {
public readonly items : number [] = Array ( 1000 ) .fill ( 1 ) .map ((item , index) => item + index);
constructor ( private renderer : Renderer2 ) {}
public onIntersection ({ target , visible } : { target : Element ; visible : boolean }) : void {
this . renderer .addClass (target , visible ? 'active' : 'inactive' );
this . renderer .removeClass (target , visible ? 'inactive' : 'active' );
}
}