在使用Anguarjs进行web开发或者进行SPA(single page application)开发时,往往会遇到下面这样的问题。

刷新页面时,页面会出现一些乱码,这里的乱码具体是指`{{expression}}`或者`{{expression | filter}}`这种形式的表达式乱码,然后这些乱码又快速的消失了,然后页面就正常了。这个问题的原因是,在一些现代浏览器,比如Chrome,Firefox等中尤为严重。当然还跟环境的网络速度有关。

出现这个问题的根本原因是,JavaScript操作DOM都是在DOM加载完成(DOM Ready)之后的才进行的。换句话说,Angularjs只会在DOM Ready之后才回去解析html模版以及Angularjs的directive,在这之前html模版中的内容会被原封不动的展示在页面,这时候就会出现所谓的乱码问题。

那么我们如何解决这个问题呢?

Angularjs官方针对这个问题提供了原生的解决方案,就是我们今天要说的主角 ng-cloak 指令。

我们先来看一下Angularjs的源码中对这个 ng-cloak 是如何实现的。

Angularjs将 ng-cloak 实现为directive,其代码如下,

!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样式。其中部分的代码是这样的,

[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的时候,将相关元素隐藏起来,这样页面就不会出现乱码了。

当DOM Ready的时候,Angularjs开始解析指令。我们来看一下 ng-cloak 这个指令都做了哪些事情,

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这个指令来实现。

使用Angularjs的ng-cloak指令避免页面乱码的更多相关文章

  1. 走进AngularJs(二) ng模板中常用指令的使用方式

    通过使用模板,我们可以把model和controller中的数据组装起来呈现给浏览器,还可以通过数据绑定,实时更新视图,让我们的页面变成动态的.ng的模板真是让我爱不释手.学习ng道路还很漫长,从模板 ...

  2. 带你走近AngularJS - 创建自己定义指令

    带你走近AngularJS系列: 带你走近AngularJS - 基本功能介绍 带你走近AngularJS - 体验指令实例 带你走近AngularJS - 创建自己定义指令 ------------ ...

  3. 带你走近AngularJS 之创建自定义指令

    带你走近AngularJS 之创建自定义指令 为什么使用AngularJS 指令? 使用过 AngularJS 的朋友应该最感兴趣的是它的指令.现今市场上的前端框架也只有AngularJS 拥有自定义 ...

  4. AngularJS的表达式、指令的学习(2)

    最近没有那么忙,就来系统学习一下AngularJS吧,昨天简单的认识了一下,今天就从表达式入手吧,嘿嘿. 一.AngularJS 表达式 AngularJS表达式写在双大括号内:{{expressio ...

  5. AngularJS常用插件与指令收集

    angularjs 组件列表 bindonce UI-Router Angular Tree angular-ngSanitize模块-$sanitize服务详解 使用 AngularJS 开发一个大 ...

  6. angularjs 创建自定义的指令

    创建自定义的指令 除了 AngularJS 内置的指令外,我们还可以创建自定义指令. 你可以使用 .directive 函数来添加自定义的指令. 要调用自定义指令,HTMl 元素上需要添加自定义指令名 ...

  7. AngularJS:directive自定义的指令

    除了 AngularJS 内置的指令外,我们还可以创建自定义指令. 你可以使用 .directive 函数来添加自定义的指令. 要调用自定义指令,HTML 元素上需要添加自定义指令名. 使用驼峰法来命 ...

  8. 项目部署到weblogic后页面乱码问题

    问题描述: windows环境下,将项目部署到weblogic运行startWebLogic.cmd启动weblogic后,浏览器访问页面乱码问题,在Tomcat不会乱码. 请不要看着博文就直接改了, ...

  9. maven-eclipse 中index.html页面乱码

    maven-eclipse 中index.html页面乱码: pox.xml修改: <project> -- <properties> <argLine>-Dfil ...

随机推荐

  1. 戴尔3542安装ubuntu时出现:failed to lead ldlinux.c32

    解决办法: 1. 开机未进入系统是连续敲击F2,进入BIOS2.在 BIOS 的Boot菜单下,将Secure Boot 改为 Disabled3. 将Boot List Option 改为 Lega ...

  2. bzoj3884 上帝与集合的正确用法

    a^b mod P=a^(b mod phi(p)) mod p,利用欧拉公式递归做下去. 代码 #pragma comment(linker,"/STACK:1024000000,1024 ...

  3. 利用Python实现从百度下载图片到本地磁盘

    import urllib.request import os import re url=r'http://image.baidu.com/search/index?tn=baiduimage&am ...

  4. html5开发移动页面去掉点击出现的透明阴影----&&-----元素垂直居中

    [摘要:做好的页里正在脚机端测试时,发明局部扫瞄器,tap后会涌现一个半通明的灰色配景,(被批...),起先认为是outline作祟,减上后发明出反映,末了发明是tap后的配景下明,要重设那个]   ...

  5. phonegap android 输入法弹出会遮盖表单框的解决办法

    phonegap android 当页面内容比较多,表单超出屏幕范围时,点击输入,输入法会遮盖住表单框,而且无法向上滑动. 经过测试发现,是由于config.xml中设置了 FullScreen 的全 ...

  6. C# ListView得到选中项及子项

    private void listViewEx_MouseClick(object sender, MouseEventArgs e) { ListViewItem lv = listViewEx.G ...

  7. 【实践】js实现简易的四则运算计算器

    最近看了一个大神推荐的某公司面试程序员的js 面试题,题目是用js 做一个计算器于是跟着大神的思想自己做了一下 ps:功能还没有完善好毕竟自己还是一只菜鸟还在不断学习中. 闲话不多说先上css代码 & ...

  8. 关于JSON

    JSON:一种数据交换格式,不是一种编程语言.(JSON 语法是 JavaScript 对象表示法语法的子集.) 什么是 JSON ? JSON 指的是 JavaScript 对象表示法(JavaSc ...

  9. 初始angular框架(2)

    看文档看不懂吧  那就应该看看点例子  看什么例子呢  看看视频教程  一般老师会把一些重要的地方着重讲解的  不懂就反复的看

  10. Java数据结构之字符串模式匹配算法---KMP算法2

    直接接上篇上代码: //KMP算法 public class KMP { // 获取next数组的方法,根据给定的字符串求 public static int[] getNext(String sub ...