解决AngularJS加载时页面闪烁(错乱)的几种方式及原理

原因:

AngularJS 应用在加载时,文档可能会由于AngularJS 代码未加载完而出现显示 AngularJS 代码(如2),进而会有闪烁的问题,也就是在加载请求的时候页面会看到一瞬间的错乱。
确切的说就是由于JavaScript去操作DOM,都会等待DOM加载完成(DOM ready)。同样AngularJS会在DOM ready之后才会去解析html view Template。页面错乱闪烁就是发生在AngularJS解析之前。
专业名词叫:Flash of Unrendered Content ,简称FOUC。

解决方法:

1. ng-bind

用ng-bind将内容同元素绑定在一起避免这个问题。

1
ng-bind

2. ng-cloak

ng-cloak 指令就是为了防止该问题而生。

1
<div ng-cloak>{{ 1 + 1 }}</div>

页面内使用次数无限制,且无参数。

ng-cloak原理:
ng-cloak实现原理为一个directive,在页面初始化时在DOM的head增加一行CSS代码,如下:

1
<style type="text/css">@charset "UTF-8";[ng\:cloak],[ng-cloak],[data-ng-cloak],[x-ng-cloak],.ng-cloak,.x-ng-cloak,.ng-hide:not(.ng-hide-animate){display:none !important;}ng\:form{display:block;}</style>

AngularJS将带有ng-cloak的元素设置为display:none。
在等到AngularJS解析到带有ng-cloak节点的时候,会把元素上ng-cloak attribute和calss同时remove掉,这样就防止了节点的闪烁。
查阅AngularJS源码可以在最后一行看到实现代码:

1
!window.angular.$$csp() && window.angular.element(document).find('head').prepend('<style type="text/css">@charset "UTF-8";[ng\\:cloak],[ng-cloak],[data-ng-cloak],[x-ng-cloak],.ng-cloak,.x-ng-cloak,.ng-hide:not(.ng-hide-animate){display:none !important;}ng\\:form{display:block;}</style>');

看上去问题已经解决了。
但是!如果浏览器的速度比AngularJS在head中加入css的速度还快这方法就失效了。
怎么办?那就事先手动把这些css加入我们的样式文件然后引入head里。