Quiero seleccionar el elemento <a> por className cuando su enlace de enrutador está activo, pero devuelve null
código navbar.component.html :
<nav class="profile-navbar"> <ul> <li class="posts-item"> <a [routerLink]="['/app/profile', username, 'posts']" routerLinkActive="active-link" >Posts</a > </li> <li class="images-item"> <a [routerLink]="['/app/profile', username, 'images']" routerLinkActive="active-link" >Images</a > </li> </ul> </nav>código navbar.component.ts :
import { AfterViewInit, Component, OnInit } from '@angular/core'; @Component({ selector: 'profile-navbar', templateUrl: './navbar.component.html', styleUrls: ['./navbar.component.scss'] }) export class NavbarComponent implements OnInit, AfterViewInit { constructor() { } ngOnInit(): void { } ngAfterViewInit(): void { const activeLink = document.querySelector('.active-link'); console.log(activeLink) } }¿Cómo puedo seleccionar el elemento basado en la clase routerLinkActive?
Para obtener una serie de "divs", puede usar una variable de referencia de plantilla y ViewChildren. Cuando tiene ViewChildren, puede encontrar el elemento con una clase u otra propiedad.
En el caso de routerLinks, el enfoque es similar, pero puede tener en ViewChildren el [routerLinksActive viendo como "ElementRef" y viendo como "RouterLinkActive"
Algo como
//links are the "RouterLinkActive" @ViewChildren(RouterLinkActive) links:QueryList<RouterLinkActive> //lisk are the "RouterLinkAvtive" but seeing as ElementRef @ViewChildren(RouterLinkActive,{read:ElementRef}) linksElements:QueryList<ElementRef> @ViewChild('indicator') indicator:ElementRef constructor(private router: Router) {} ngOnInit() { this.router.events.pipe( filter(x=>x instanceof NavigationEnd), startWith(null)).subscribe(res=>{ //we need enclosed in a setTimeout because when the event NavigationEnd //happens, Angular are not add the class "active-links" // nor link isActive=true setTimeout(()=>{ //first find the "index" in the QueryList const index=(this.links.map( (x:RouterLinkActive,i:number)=>({isActive:x.isActive,index:i})) .find(x=>x.isActive) || {index:-1}).index //it's the same index in the ElementRef if (index>=0) { const el=this.linksElements.find((_,i)=>i==index) //We use the "el" to change the style.top of the indicator this.indicator.nativeElement.style.top= el.nativeElement.offsetTop+'px' } else { this.indicator.nativeElement.style.top='-100px' } }) }) }Dónde
<nav class="profile-navbar"> <ul> <li class="posts-item"> <a [routerLink]="['/hello']" routerLinkActive="active-link" >Posts</a > </li> <li class="images-item"> <a [routerLink]="['/by']" routerLinkActive="active-link" >Images</a > </li> </ul> <div #indicator class="indicator"></div> </nav>como se muestra en este stackblitz
No puede usar este LifeCycleHook, pruebe ngDoCheck() en su lugar o escuche los cambios de ruta ( ¿Cómo detectar un cambio de ruta en Angular? ) y haga su selección en función del evento o, mejor aún, simplemente utilícelo en su archivo .css:
a.active { /* your style */ }Si solo desea diseñarlo, generalmente no es necesario seleccionarlo, pero en su caso con el cálculo de translate3d y scaleX, no estoy seguro ...