Я хочу выбрать элемент <a> по className, когда его ссылка на маршрутизатор активна, но он возвращает null
Код 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>
Код 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.info(activeLink)
}
}
Как я могу выбрать элемент, основанный на классе routerLinkActive?
Я хочу добавить индикатор активной ссылки, как стиль в этом codepen codepen.io/ohsoren/pen/QNoQwX
@AsmaaMahmoud, почему бы не использовать .active-link::after{......}?
@Eliseo, индикатор не является частью самой активной ссылки, это отдельный элемент, который перемещается под всеми ними.
@AsmaaMahmoud, вы можете использовать ViewChildren, проверьте мой ответ :)



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Вы не можете использовать этот LifeCycleHook вместо этого, попробуйте ngDoCheck() или прослушайте изменения маршрута (Как обнаружить изменение маршрута в Angular?) и сделайте свой выбор на основе события или, что еще лучше, просто используйте в своем файле .css:
a.active {
/* your style */
}
Если вы просто хотите стилизовать его, обычно его не нужно выбирать, но в вашем случае с расчетом translate3d и scaleX я не уверен...
Он возвращает первую ссылку с атрибутом routerLinkActive со значением «активная ссылка».
Извините, я пропустил это, я только что обновил свой ответ!
Нет проблем, я только что использовал querySellectorAll, и он отлично работает, но мне было интересно, есть ли способ получить только активную ссылку.
И почему выбор элемента с именем класса не работает?
Извините еще раз, я неправильно понял ваш вопрос. Класс следует применять, но только после ngAfterViewInit. Так что просто используйте ngAfterViewChecked или просто используйте селектор css.
Спасибо большое, вот так ngAfterViewChecked(), но я думаю нехорошо вызывать функцию позиционирования индикатора внутри ngAfterViewChecked(), не так ли?
@AsmaaMahmoud Вы должны использовать ngDoCheck() и вызывать свой метод оттуда или, что еще лучше, использовать событие маршрутизатора так, как предложил Элисео.
Чтобы получить серию «div», вы можете использовать ссылочную переменную шаблона и ViewChildren. Когда у вас есть ViewChildren, вы можете найти элемент с классом или другим свойством.
В случае с routerLinks подход аналогичен, но вы можете иметь в ViewChildren [routerLinksActive, видимый как "ElementRef" и видящийся как "RouterLinkActive"
Некоторым нравится
//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'
}
})
})
}
Где
<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>
как показано в этот стекблиц
Зачем вам нужен доступ к этому элементу, если я могу спросить?