Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS strategy to prevent flash-of-unstyled-content for a class

I have an AngularJS project, I want to prevent a FOUC during page load on a classname. I've read about ng-template but that seems useful only for content within a tag.

<body class="{{ bodyClass }}"> 

I would like it to be "login" on page load. Any strategy for this? Or do I just have to fudge it and load it as 'login' and manually use javascript to to tweak the DOM just for this instance.

like image 313
Casey Flynn Avatar asked Apr 18 '13 04:04

Casey Flynn


People also ask

What is flash of unstyled content How do you avoid FOUC?

In an attempt to avoid unstyled content, front-end developers may choose to hide all content until it is fully loaded, at which point a load event handler is triggered and the content appears, though an interruption of loading might leave behind a blank page, to which unstyled content would be preferable.

How do you use NG cloak?

Definition and UsageThe ng-cloak directive prevents the document from showing unfinished AngularJS code while AngularJS is being loaded. AngularJS applications can make HTML documents flicker when the application is being loaded, showing the AngularJS code for a second, before all code are executed.


2 Answers

What you are looking for is ng-cloak.
You have to add it like this:

<body class="{{ bodyClass }}" ng-cloak> 

and this will prevent unwanted flashing.
Link to docs about this.

Edit:
It is also advisable to put the snippet below into your CSS file, according to docs.

"For the best result, the angular.js script must be loaded in the head section of the html document; alternatively, the css rule above must be included in the external stylesheet of the application."

[ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak {     display: none !important; } 
like image 96
the-lay Avatar answered Sep 20 '22 19:09

the-lay


One of the problems that you're facing is that the browser will display the <body> element before AngularJS has loaded and started manipulating the DOM. What other people said about ng-class is correct, it will do the right class applying but you still need to not show anything before Angular is ready.

In previous versions of Angular you could do this:

<body style="display:none" ng-show="true" ng-class="{{bodyClass}}"> 

In recent versions this doesn't work however because ng-show does its visibility by adding and removing the ng-hide class (which is less specific than an element attribute)

What I've been doing recently is this:

<head> ...     <style> <!-- Or you could include this in an existing style sheet -->         .ng-cloak {             display: none !important;         }     </style>     </head> <body class="ng-cloak" ng-cloak ng-class="{{bodyClass}}"> 

Doing it this way means that the <body> will be immediately hidden by the style for the ng-cloak class. When Angular does start up it will process all of the directives include ng-class and ng-cloak, so your <body> element will then have the right class and be visible.

Read more here ng-cloak directive

like image 45
Nicholas Green Avatar answered Sep 22 '22 19:09

Nicholas Green