I apologize in advance for the length of this, but I want to make sure I'm explaining this correctly.
I'm rebuilding my current portfolio site https://www.gelerinter.com from AngularJS to Angular 16. One of the key pieces of the site is that you can dynamically change the CSS on the site via a drop down menu. I'm almost there on the new site but I've hit a small snag that I can't seem to get past.
I have a script in app.component.ts
that successfully changes the css file as well as sets the original one to the default css. However, it seemingly happens a fraction of a second too late since the whole page renders fine, except, on the initial page render, the top nav simply doesn't show up. The developer console shows it to be present on the page (but the invisible blocks that claim to be the nav are not in the right place, anyway) but you can't see it. Once you change the CSS, the nav shows up perfectly. If you change back to the default CSS, the nav is perfect. It's that initial load.
Things I've tried:
angular.json
.styleUrls
in either/both of app.component.ts
and app-navigation.ts
EFFECT: Shows up great on initial load, but then, when changing the CSS, remnants of the default css stick around and mess up the page - specifically the nav area.
index.html
EFFECT: Either the same as above, or no CSS at all loads
ngOnInit()
or inside the constructor
of either/both of app.component.ts
and app.navigation.ts
. I also did this in app.header.ts
which is what directly loads <app-navigation>
.EFFECT: This is the best I've gotten. Everything works as intended, except that the nav seemingly loads on the initial page load before any CSS, so I can't actually see the nav until I change the CSS.
Here is the current best I've got: https://ng.gelerinter.com. (Yes, I know it's got other work to be done besides this. I'm in the middle of the rebuild and am stuck at this part.) I do also notice something that might be related. When I change the CSS on the current site, I get a fraction of a second of blankness, then it shows up with the new CSS. On the new site, I get that same fraction of a second of transition, but, instead of blankness, I see the site sans CSS. It seems that the current site is waiting for the CSS before rendering anything but the new site is rushing it and having the effect of a glimpse of no CSS as well as possibly why the nav isn't getting the CSS on the initial load.
Here is the code to app.component.ts
and app.compenent.html
if needed. I can add other code if requested:
app.component.ts - Feel free to ignore the animations stuff. That's not relevant to this .
import { Component, Inject, OnInit } from '@angular/core';
import { ViewEncapsulation, HostListener, ElementRef } from '@angular/core';
import { trigger, state, style, animate, transition} from '@angular/animations';
import { DOCUMENT } from '@angular/common';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
encapsulation: ViewEncapsulation.None,
animations: [
trigger('BTTfade', [
state('false', style({ opacity: 0 })),
state('true', style({ opacity: 1 })),
transition('false => true', animate('500ms ease-in')),
transition('true => false', animate('500ms ease-out'))
]),
]
})
export class AppComponent implements OnInit {
offset = 320;
duration = 300;
fadeIn = false;
constructor(private el: ElementRef, @Inject(DOCUMENT) private document: Document) {
this.loadStyle('default');
}
ngOnInit(): void {
// this.loadStyle('default');
}
loadStyle(styleName: string) {
const head = this.document.getElementsByTagName('head')[0];
let themeLink = this.document.getElementById(
'theme-link'
) as HTMLLinkElement;
if (themeLink) {
themeLink.href = `assets/css/style-${styleName}.css`;
} else {
const style = this.document.createElement('link');
style.id = 'theme-link';
style.rel = 'stylesheet';
style.type = 'text/css';
style.href = `assets/css/style-${styleName}.css`;
head.appendChild(style);
}
}
@HostListener('window:scroll',['$event'])
onScroll(e) {
if (window.scrollY > this.offset) {
this.fadeIn = true;
}
else {
this.fadeIn = false;
}
}
goToTop(){
let element = this.el.nativeElement.querySelector('#mainPage')
element.scrollIntoView();
}
}
app.component.html
<div id="main-body">
<app-header></app-header>
<div id="wrapper">
<router-outlet></router-outlet>
<a (click)="goToTop()" class="back-to-top" [@BTTfade]="fadeIn">Back to Top</a>
</div> <!-- end main content -->
<br clear="all" />
<app-footer></app-footer>
</div>
In my research I came across something about using APP_INITIALIZER
but didn't understand if/how it would help here and how to implement it. If that's the answer, I humbly request guidance on how to do that.
I believe that's it for now. Thank you for your assistance.
I'm still not 100% sure why it was doing what it was doing, but I figured out that it had something to do with the CSS of the navigation, specifically in the default styling.
In an odd fix, putting the call to <app-navigation>
earlier in the code solved the issue. I had to modify the CSS across all the styles to make everything stay where I wanted it to stay, but hey, isn't that the point of CSS?
If anyone has input on thoughts as to why this was occurring, I'm still open to hear them.