Reputation: 317
My app is structured like this:
<nav></nav>
<router-outlet></router-outlet>
<footer></footer>
In the router-outlet I have different components based on the route. In a few of those pages I need to access the DOM elements of either the nav or the footer for things like pageYOffset, height and etc. for sticky positioning. I know of things like ViewChild, Renderer2 and ElementRef but not really sure how it would work. Do I create a service? What might that look like?
Upvotes: 4
Views: 11583
Reputation: 73781
Assuming that the child components are of type NavComponent
and FooterComponent
, you can retrieve the corresponding DOM elements with @ViewChild(..., { read: ElementRef })
in ngAfterViewInit
:
@ViewChild(NavComponent, { read: ElementRef }) private navElementRef: ElementRef;
@ViewChild(FooterComponent, { read: ElementRef }) private footerElementRef: ElementRef;
ngAfterViewInit() {
const navElement = this.navElementRef.nativeElement;
const footerElement = this.footerElementRef.nativeElement;
...
}
See this stackblitz for a demo.
These elements can be made accessible to other parts of the application with a simple service:
export class AppElementsService {
public navElement: HTMLElement;
public footerElement: HTMLElement;
}
and set in the application component:
@ViewChild(NavComponent, { read: ElementRef }) private navElementRef: ElementRef;
@ViewChild(FooterComponent, { read: ElementRef }) private footerElementRef: ElementRef;
constructor(private appElementsService: AppElementService) { }
ngAfterViewInit() {
this.appElementsService.navElement = this.navElementRef.nativeElement;
this.appElementsService.footerElement = this.footerElementRef.nativeElement;
}
Note: you may need to set the display
style attribute of the nav
and footer
components to block
or inline-block
in order to get the position and size of the corresponding elements.
Upvotes: 4