[英]AngularJS: How to show preload or loading until page is loaded completely?
I've an image gallery site where I'm getting all images and image related data from the database as json format in my controller and then by using ng-repeat I'm binding them with the html. 我有一个图像库网站,我在控制器中以json格式从数据库中获取所有图像和图像相关数据,然后使用ng-repeat我将它们与html绑定。 Now, data are loaded early but images are loaded late, so images are scattered. 现在,数据被提前加载,但图像加载较晚,因此图像分散。 How to solve this. 怎么解决这个问题。 I don't want to use setTimeOut. 我不想使用setTimeOut。
The sample code is as below:- 示例代码如下: -
<!DOCTYPE html>
<html lang="en" class="no-js" ng-app="cps">
<body ng-controller="CPSController">
<div>
<li ng-repeat="image in images" class="shown">
<a id="{{image.imageid}}" ng-click="openimage(image.imageid)">
<img idx="id-thumb-{{$index}}" ng-src="/imagedisplay/{{image.imageid}}" alt="" style="">
<div class="meta_info">
<h3>{{image.imagename}}.</h3>
<div class="callto">
<div class="actions">
<span><img src="img/artist.svg" alt="">{{image.ownername}}</span>
<span><img src="img/likes.svg" alt="">{{image.likes}}</span>
<span><img src="img/views_small.svg" alt="">{{image.views}}</span>
</div>
<div class="category">
Art Category
</div>
</div>
</div>
</a>
</li>
</div>
</body>
</html>
<script>
var cps = angular.module('cps', []);
cps.controller('CPSController', function($scope, $http, $compile){
$scope.products = [];
$http.get("/alldata/").success(function(data){
if(data != "null")
{
for(i=data.length-1; i>=0; i--){
$scope.products.push(data[i]);
}
$scope.sendOrder('views', 'likes', 'timestamp', 2);
}else{
//$('#noImages').show();
}
/*setTimeout(function(){
$("[idx^='id-thumb']").show();
});*/
});
});
</script>
# UPDATE [August 2017]
Same answer as below except we could work with the load
event on window
instead of DOMContentLoaded
on document
. 答案如下,除了我们可以在window
上使用load
事件而不是在document
上使用DOMContentLoaded
。 This will ensure that all assets (such as images) in the window
are loaded . 这将确保加载 window
中的所有资源(例如图像)。
window.addEventListener("load", function(event) {
...
})
We don't have to force Angular where vanilla javascript
can suffice. 我们不必强制Angular,其中vanilla javascript
就足够了。 This is how it worked for my AngularJS
project 这就是我的AngularJS
项目的工作方式
Added this to the body tag. 将其添加到body标签中。 It will be removed with a script tag once HTML Content Loads 一旦HTML内容加载,它将使用脚本标记删除
<div id="page-loading">
<img style="display:block; margin:0 auto;" src="styles/img/page-loading.gif">
</div>
script
tag right under the image. script
标签正好在图像下方。
<script type="text/javascript">
document.addEventListener("DOMContentLoaded", function(event) {
/*VANILLA JAVASCRIPT*/
var element = document.getElementById("page-loading");
element.parentNode.removeChild(element);
/* OR WITH jQuery*/
$('#page-loading')
.fadeOut('slow');
});
</script>
DOMContentLoaded
event will ensure that the the callback
is executed when all the images,fonts,js and other assets
have been loaded. DOMContentLoaded
事件将确保在加载所有images,fonts,js and other assets
时执行callback
。
Good Luck. 祝好运。
I'm not sure if this is the right approach, but what I usually do is that I have a $scope.loaded
variable which has the state of the page. 我不确定这是否是正确的方法,但我通常做的是我有一个$scope.loaded
变量,它具有页面状态。 If the page is loaded, the div you want to show is shown... If it's loading, the div with the loader is shown. 如果页面已加载,则显示要显示的div ...如果正在加载,则显示带有加载程序的div。 Have a look at this plunk to get what I'm trying to say. 看看这个插件来得到我想说的话。
I'm pasting the Plunkr code here as well. 我也在这里粘贴Plunkr代码。
Javascript 使用Javascript
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope, $timeout) {
$scope.loaded = true;
$scope.text = 'Nothing loaded yet.';
$scope.loadSomething = function () {
$scope.loaded = false;
$timeout(function() {
// Simulates loading
$scope.text = 'Hello World';
$scope.loaded = true;
}, 2000);
};
});
HTML HTML
<body ng-controller="MainCtrl">
<button class="btn btn-primary" ng-click="loadSomething()">Load Something</button>
<br/>
<div ng-hide="loaded">
Loading...
</div>
<div ng-show="loaded">
<p>{{ text }}</p>
</div>
Do let me know if you need any further help. 如果您需要任何进一步的帮助,请告诉我。
Try this: 尝试这个:
angular.element($window).bind('load', function() {
$scope.yourLoaderDiv=true;
});
While @chotesah answer is just right I can suggest you go another way and use preloaders for each image (something like Facebook on page load). 虽然@chotesah答案恰到好处,但我可以建议你采用另一种方式,并为每个图像使用预加载器(像页面加载时的Facebook一样)。
Try this module . 试试这个模块 。 You'll need to change few lines: 你需要换几行:
// Add module dependency
angular.module('app', ['angular-preload-image']);
…
<img preload-image idx="id-thumb-{{$index}}" ng-src="/imagedisplay/{{image.imageid}}" default-image="[URL]" fallback-image="[URL]" />
After that look for nifty image preloaders at codrops . 之后在codrops寻找漂亮的图像预加载器 。
I have struggled with same issue. 我一直在努力解决同样的问题。 Here is what working on my side where i am showing multiple loading image for each different section based on promise. 以下是在我这边工作的地方,我根据承诺为每个不同的部分显示多个加载图像。 For this purpose i have created a directive. 为此,我创建了一个指令。
My html looks something like below. 我的HTML看起来像下面。
<mi-loading promise="Loading"></mi-loading>
Angularjs directive. Angularjs指令。
(function () {
var module = angular.module('mi-loading', []);
module.directive('miLoading', function () {
return {
restrict: 'E',
scope: {
promise: '='
},
link: function ($scope, $element, $attrs) {
$scope.IsLoading = true;
$scope.$watch('promise', function (prom) {
if (!prom) {
$scope.IsLoading = false;
return;
}
prom.success(function () { $scope.IsLoading = false; });
});
},
template: '<div ng-show="IsLoading" class="spinner" style="height:300px"></div>'
};
});
})();
and finally the usage, 最后用法,
var getData = function ()
{
var Promise = myservice.getMyData($scope);
$scope.Loading = Promise;
};
CSS CSS
.spinner {
min-width: 30px;
min-height: 30px;
}
.spinner:before {
content: 'Loading…';
position: absolute;
top: 50%;
left: 50%;
width: 24px;
height: 24px;
margin-top: -13px;
margin-left: -13px;
}
.spinner:not(:required):before {
content: '';
border-radius: 50%;
border: 3px solid #ccc;
/*border-top-color: #03ade0;*/
border-top-color: #4187b5;
animation: spinner .6s linear infinite;
-webkit-animation: spinner .6s linear infinite;
}
To achieve it, i am loading all my scripts at the end of the body. 为了实现它,我正在加载我身体末端的所有脚本。 Before my app-wrapper-div i place a postion fixed "loading"-div. 在我的app-wrapper-div之前,我将位置固定为“loading”-div。 It is shown immediately before other scripts are loaded. 它会在加载其他脚本之前立即显示。
At the end of the body, after my scripts are included, i place an angular directive, that fadeOut and remove the loading-div. 在主体的末尾,在我的脚本被包含之后,我放置一个角度指令,即fadeOut并删除loading-div。
The code: 编码:
<html ng-app="myApp">
<head>
<!-- the only file loaded in the head -->
<link rel="stylesheet" href="/.../appLoadingScreen.css"/>
</head>
<body>
<div id="appLoadingScreen">
<div id="appLoadingScreenCenterWrap">
<h1 id="appLoadingScreenHeader">APP TITLE</h1>
<p id="appLoadingScreenMsg">App is loading!</p>
</div>
</div>
<div id="appWrapper" ng-controller="appCtrl">
...
</div>
<!-- All stylesheet includes -->
...
<!-- All script includes -->
...
<script src="/.../hideLoadingScreen.js"></script>
<hide-loading-screen></hide-loading-screen>
</body>
</html>
And the hideLoadingScreen directive: 而hideLoadingScreen指令:
(function() {
var app = angular.module('appModule');
app.directive('hideLoadingScreen', function($timeout) {
return {
restrict: 'E',
link: function() {
$timeout(function() {
$("#appLoadingScreen").fadeOut(600, function(){$(this).remove();});
}, 400);
}
};
});
})();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.