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 相关文章推荐
用js解决数字不能换行问题
Aug 10 Javascript
JavaScript Accessor实现说明
Dec 06 Javascript
jquery使用jxl插件导出excel示例
Apr 14 Javascript
三种AngularJS中获取数据源的方式
Feb 02 Javascript
JS简单实现String转Date的方法
Mar 02 Javascript
jquery对所有input type=text的控件赋值实现方法
Dec 02 Javascript
canvas轨迹回放功能实现
Dec 20 Javascript
react实现点击选中的li高亮的示例代码
May 24 Javascript
Vue filter格式化时间戳时间成标准日期格式的方法
Sep 16 Javascript
使用 js 简单的实现 bind、call 、aplly代码实例
Sep 07 Javascript
vue 返回上一页,页面样式错乱的解决
Nov 14 Javascript
Ajax异步刷新功能及简单案例
Nov 20 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中关于抽象(abstract)类和抽象方法的问题分析
2014/01/03 PHP
PHP定时更新程序设计思路分享
2014/06/10 PHP
ThinkPHP权限认证Auth实例详解
2014/07/22 PHP
老生常谈PHP中的数据结构:DS扩展
2017/07/17 PHP
采用CSS和JS,刚好我最近有个站点要用到下拉菜单!
2006/06/26 Javascript
jQuery AJAX 调用WebService实现代码
2010/03/24 Javascript
jQuery EasyUI中对表格进行编辑的实现代码
2010/06/10 Javascript
jquery控制页面部分刷新的方法
2015/06/24 Javascript
jQuery的选择器中的通配符[id^='code']或[name^='code']及jquery选择器总结
2015/12/24 Javascript
JS读写CSS样式的方法汇总
2016/08/16 Javascript
js获取form表单所有数据的简单方法
2016/08/18 Javascript
Nodejs--post的公式详解
2017/04/29 NodeJs
jquery Form轻松实现文件上传
2017/05/24 jQuery
vue router仿天猫底部导航栏功能
2017/10/18 Javascript
详解Javascript中new()到底做了些什么?
2018/03/29 Javascript
如何解决.vue文件url引用文件的问题
2019/01/18 Javascript
详解用Webpack与Babel配置ES6开发环境
2019/03/12 Javascript
Vue批量图片显示时遇到的路径被解析问题
2019/03/28 Javascript
JS实现的雪花飘落特效示例
2019/12/03 Javascript
JS实现拼图游戏
2021/01/29 Javascript
利用vue3+ts实现管理后台(增删改查)
2020/10/30 Javascript
python 中文乱码问题深入分析
2011/03/13 Python
matplotlib.pyplot绘图显示控制方法
2019/01/15 Python
让Django的BooleanField支持字符串形式的输入方式
2020/05/20 Python
Stella McCartney官网:成衣、包袋、香水、内衣、童装及Adidas系列
2018/12/20 全球购物
英文自荐信格式
2013/11/28 职场文书
优秀求职信范文分享
2014/01/26 职场文书
党课知识竞赛主持词
2014/04/01 职场文书
党员干部反四风民主生活会对照检查材料思想汇报
2014/10/12 职场文书
2014年世界艾滋病日演讲稿
2014/11/28 职场文书
上课讲话检讨书范文
2015/05/07 职场文书
2019银行员工个人工作自我鉴定
2019/06/27 职场文书
导游词之绍兴柯岩古镇
2020/01/09 职场文书
使用 JavaScript 制作页面效果
2021/04/21 Javascript
Python合并多张图片成PDF
2021/06/09 Python
python实现会员管理系统
2022/03/18 Python