使用Angularjs的ng-cloak指令避免頁面亂碼

在使用Anguarjs進行web開發或者進行SPA(single page application)開發時,每每會遇到下面這樣的問題。css

刷新頁面時,頁面會出現一些亂碼,這裏的亂碼具體是指`{{expression}}`或者`{{expression | filter}}`這種形式的表達式亂碼,而後這些亂碼又快速的消失了,而後頁面就正常了。這個問題的緣由是,在一些現代瀏覽器,好比Chrome,Firefox等中尤其嚴重。固然還跟環境的網絡速度有關。html

出現這個問題的根本緣由是,JavaScript操做DOM都是在DOM加載完成(DOM Ready)以後的才進行的。換句話說,Angularjs只會在DOM Ready以後纔回去解析html模版以及Angularjs的directive,在這以前html模版中的內容會被原封不動的展現在頁面,這時候就會出現所謂的亂碼問題。web

那麼咱們如何解決這個問題呢?express

Angularjs官方針對這個問題提供了原生的解決方案,就是咱們今天要說的主角 ng-cloak 指令。瀏覽器

咱們先來看一下Angularjs的源碼中對這個 ng-cloak 是如何實現的。網絡

Angularjs將 ng-cloak 實現爲directive,其代碼以下,app

!angular.$$csp()
&& 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{display:none !important;}' +
        'ng\\:form{display:block;}' +
        '.ng-animate-block-transitions{transition:0s all!important;-webkit-transition:0s all!important;}' +
        </style>');

 

你們不要對這一坨代碼感到畏懼,其實它作的事很簡單,就是在html的中 head 標籤中插入一段內聯的css樣式。其中部分的代碼是這樣的,ide

[ng\\:cloak],
[ng-cloak],
[data-ng-cloak],
[x-ng-cloak],
.ng-cloak,
.x-ng-cloak,
.ng-hide {
    display:none !important;
}

 

 

很顯然,Angularjs對 ng-cloak 相關的元素設置了 display: none !important 這樣一個屬性,目的就是隱藏相關元素。這樣在在DOM尚未Ready的時候,將相關元素隱藏起來,這樣頁面就不會出現亂碼了。spa

當DOM Ready的時候,Angularjs開始解析指令。咱們來看一下 ng-cloak 這個指令都作了哪些事情,code

var ngCloakDirective = ngDirective({
    compile: function(element, attr) {
        attr.$set('ngCloak', undefined);
        element.removeClass('ng-cloak');
    }
});

可見,當Angularjs開始解析 ng-cloak 指令的時候,又會把這個樣式給去除掉。這樣頁面又顯示了。

經過以上分析,咱們知道了使用 ng-cloak 指令來避免頁面出現亂碼的原理,其實經過先隱藏後顯示來規避了DOM還沒有Ready這段時間的真空期。

理論是美好的,可是現實每每會給我一個響亮的耳光。

在實際使用的過程當中,咱們要想使上面的過程完美表現,就必需要先在 head 標籤中先引入Angularjs的源碼,而不能在頁面的最後引入Angularjs文件。

由於後者會形成這樣一種狀況:在Angularjs文件還沒引入時,意味着還沒給 ng-cloak 相關元素作隱藏處理,頁面就已經展現了,這是頁面仍然會出現亂碼。

可是通常性的原則告訴咱們, 應該把css文件放在頭部,把js文件放在尾部 。那麼咱們如何解決這個矛盾呢?

解決方案是,咱們手動在 head 中將 ng-cloak 相關的元素設置爲隱藏,即添加以下的代碼,

<head>
    <style>
        [ng:cloak],
        [ng-cloak],
        [data-ng-cloak],
        [x-ng-cloak],
        .ng-cloak,
        .x-ng-cloak {
            display:none !important;
        }
    </style>
</head>

 

或者將這一段代碼放在咱們在 head 中加載的css文件中,這樣就能夠確保頁面加載的時候,無論它有沒有DOM Ready, ng-cloak 相關元素確定是隱藏的。

若是你發如今 body 上加了 ng-cloak ,可是仍然不起做用,那麼緣由應該就是上面所描述的,這時候你就須要在 head 中添加隱藏代碼或者在引入的css文件中添加相關代碼了。

最後提一點,若是 中的表達式僅僅是展現一些文本內容,咱們能夠使用 ng-bind這個指令來實現。

相關文章
相關標籤/搜索