AngularJS页面访问时出现页面闪烁问题的解决


Posted in Javascript onMarch 06, 2016

我们知道在应用的页面或者组件需要加载数据时,浏览器和angular渲染页面都需要消耗一定的时间。这里的间隔可能很小,甚至让人感觉不到区别;但也可能很长,这样会导致让我们的用户看到了没有被渲染过的页面。

这种情况被叫做Flash Of Unrendered Content (FOUC)(K)?and is always unwanted.下面我们将要介绍几个不同的方式防止这种情况发生在我们的用户身上。

1、ng-cloak
ng-cloak指令是angular的内置指令,它的作用是隐藏所有被它包含的元素:

<div ng-cloak>
 <h1>Hello {{ name }}</h1>
</div>

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

<pre class= “prettyprint linenums”>

  [ng\:cloak],[ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak{

  Display:none ! important;

}

</pre>

<pre class= “prettyprint linenums”>
 
  [ng\:cloak],[ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak{
 
  Display:none ! important;
 
}
 
</pre>

Angular将带有ng-cloak的元素设置为display:none.

在等到angular解析到带有ng-cloak节点的时候,会把元素上ng-cloak  attribute和calss同时remove掉,这样就防止了节点的闪烁。如下:

<script type =”text/ng-template” id =”scenario.js-150”>

  It(‘should remove the template directive and css class',function(){

 Expect(element(‘.doc-example-live #template1').attr(‘ng-cloak'))

  not().toBeDefined();

   Expect(element(‘.doc-example-live #template2').attr(‘ng-cloak')).

Not().toBeDefined();

});

</script>

<script type =”text/ng-template” id =”scenario.js-150”>
 
  It(‘should remove the template directive and css class',function(){
 
 Expect(element(‘.doc-example-live #template1').attr(‘ng-cloak'))
 
  not().toBeDefined();
 
   Expect(element(‘.doc-example-live #template2').attr(‘ng-cloak')).
 
Not().toBeDefined();
 
});
 
</script>

2、ng-bind
ng-bind是angular里面另一个内置的用于操作绑定页面数据的指令。我们可以使用ng-bind代替{{ }}的形式绑定元素到页面上;

使用ng-bind替代{{  }}可以防止未被渲染的{{ }}就展示给用户了,使用ng-bind渲染的空元素替代{{ }}会显得友好很多。

上面的例子可以重写成下面那样,这样就可以防止页面出现{{ }}了

<div>
 <h1>Hello <span ng-bind="name"></span></h1>
</div>

3、resolve
当在不同的页面之间使用routes(路由)的时候,我们有另外的方式防止页面在数据被完全加载到route之前被渲染。

在route(路由)里使用resolve可以让我们在route(路由)被完全加载之前获取我们需要加载的数据。当数据被加载成功之后,路由就会改变而页面也会呈现给用户;数据没有被加载成功route就不会改变, the $routeChangeError event will get fired.【$routeChangeError事件就(不)会被激活?】

angular.module('myApp', ['ngRoute'])
.config(function($routeProvider) {
 $routeProvider
 .when('/account', {
 controller: 'AccountCtrl',
 templateUrl: 'views/account.html',
 resolve: {
  // We specify a promise to be resolved
  account: function($q) {
  var d = $q.defer();
  $timeout(function() {
   d.resolve({
   id: 1,
   name: 'Ari Lerner'
   })
  }, 1000);
  return d.promise;
  }
 }
 })
});

resolve 项需要一个key/value对象,key是resolve依赖的名称,value可以是一个字符串(as a service)或者一个返回依赖的方法。

resolve is very useful when the resolve value returns a promise that becomes resolved or rejected.

当路由加载的时候,resolve参数里的keys可以作为可注入的依赖:

angular.module('myApp')
.controller('AccountCtrl', 
 function($scope, account) {
 $scope.account = account;
});

我们同样可以使用resolve key传递$http方法返回的结果,as $http returns promises from it's method calls:

angular.module('myApp', ['ngRoute'])
.config(function($routeProvider) {
 $routeProvider
 .when('/account', {
 controller: 'AccountCtrl',
 templateUrl: 'views/account.html',
 resolve: {
  account: function($http) {
  return $http.get('http://example.com/account.json')
  }
 }
 })
});

推荐定义一个独立的service的方式来使用resolve key,并且使用service来相应返回所需的数据(这种方式更容易测试)。要这样处理的话,我们需要创建一个service:

首先,看一下accountService,

angular.module('app')
.factory('accountService', function($http, $q) {
 return {
 getAccount: function() {
  var d = $q.defer();
  $http.get('/account')
  .then(function(response) {
  d.resolve(response.data)
  }, function err(reason) {
  d.reject(reason);
  });
  return d.promise;
 }
 }
})

定义好service之后我们就可以使用这个service来替换上面代码中直接调用$http的方式了:

angular.module('myApp', ['ngRoute'])
.config(function($routeProvider) {
 $routeProvider
 .when('/account', {
 controller: 'AccountCtrl',
 templateUrl: 'views/account.html',
 resolve: {
  // We specify a promise to be resolved
  account: function(accountService) {
  return accountService.getAccount()
  }
 }
 })
});
Javascript 相关文章推荐
JavaScript 入门·JavaScript 具有全范围的运算符
Oct 01 Javascript
jquery实现更改表格行顺序示例
Apr 30 Javascript
jQuery中data()方法用法实例
Dec 27 Javascript
JavaScript中判断变量是数组、函数或是对象类型的方法
Feb 25 Javascript
jQuery动态背景图片效果实现方法
Jul 03 Javascript
深入理解JavaScript中的对象复制(Object Clone)
May 18 Javascript
Vue.js每天必学之指令系统与自定义指令
Sep 07 Javascript
javascript十六进制数字和ASCII字符之间的转换方法
Dec 27 Javascript
如何使node也支持从url加载一个module详解
Jun 05 Javascript
vue项目打包之后背景样式丢失的解决方案
Jan 17 Javascript
Windows下安装 node 的版本控制工具 nvm
Feb 06 Javascript
微信小程序实现登录注册功能
Dec 29 Javascript
JavaScript模拟数组合并concat
Mar 06 #Javascript
JavaScript模拟push
Mar 06 #Javascript
JavaScript中利用jQuery绑定事件的几种方式小结
Mar 06 #Javascript
Node.js模块封装及使用方法
Mar 06 #Javascript
JavaScript中三种异步上传文件方式
Mar 06 #Javascript
JavaScript中获取纯正的undefined的方法
Mar 06 #Javascript
JS面向对象编程详解
Mar 06 #Javascript
You might like
基于PHP静态类的原罪详解
2013/05/06 PHP
PHP快速按行读取CSV大文件的封装类分享(也适用于其它超大文本文件)
2014/04/10 PHP
php通过session防url攻击方法
2014/12/10 PHP
FastCGI 进程意外退出造成500错误
2015/07/26 PHP
PHPStrom中实用的功能和快捷键大全
2015/09/23 PHP
PHP解决中文乱码
2017/04/28 PHP
Laravel中为什么不使用blpop取队列详析
2018/08/01 PHP
列表内容的选择
2006/06/30 Javascript
可自己添加html的伪弹出框实现代码
2013/09/08 Javascript
Js 正则表达式知识汇总
2014/12/02 Javascript
jquery轮播的实现方式 附完整实例
2016/07/28 Javascript
javascript中异常处理案例(推荐)
2016/10/03 Javascript
微信小程序开发之麦克风动画 帧动画 放大 淡出
2017/04/18 Javascript
使用vue与jquery实时监听用户输入状态的操作代码
2017/09/19 jQuery
JS+HTML5实现获取手机验证码倒计时按钮
2018/08/08 Javascript
vue+django实现一对一聊天功能的实例代码
2019/07/17 Javascript
详解ES6新增字符串扩张方法includes()、startsWith()、endsWith()
2020/05/12 Javascript
JQuery实现折叠式菜单的详细代码
2020/06/03 jQuery
python使用正则表达式提取网页URL的方法
2015/05/26 Python
python实现简易版计算器
2020/06/22 Python
python无限生成不重复(字母,数字,字符)组合的方法
2018/12/04 Python
对Python使用mfcc的两种方式详解
2019/01/09 Python
python用opencv批量截取图像指定区域的方法
2019/01/24 Python
python 数据生成excel导出(xlwt,wlsxwrite)代码实例
2019/08/23 Python
如何将你的应用迁移到Python3的三个步骤
2019/12/22 Python
在python中实现求输出1-3+5-7+9-......101的和
2020/04/02 Python
pandas DataFrame 数据选取,修改,切片的实现
2020/04/24 Python
使用CSS3美化HTML表单的技巧演示
2016/05/17 HTML / CSS
HTML5探秘:用requestAnimationFrame优化Web动画
2018/06/03 HTML / CSS
英国羊绒服装购物网站:Pure Collection
2018/10/22 全球购物
2013年办公室秘书的个人自我鉴定
2013/10/24 职场文书
酒店副总经理岗位职责范本
2014/02/04 职场文书
品质标语大全
2014/06/21 职场文书
苦儿流浪记读书笔记
2015/07/01 职场文书
2019暑期安全倡议书!
2019/06/27 职场文书
英文诗歌翻译方法(赏析)
2019/08/16 职场文书