web-dev-qa-db-ja.com

AngularJS:ページが完全にロードされるまでプリロードまたはロードを表示する方法は?

私は、コントローラーからjson形式としてデータベースからすべての画像と画像関連データを取得し、ng-repeatを使用してhtmlにバインドする画像ギャラリーサイトを持っています。現在、データは早く読み込まれますが、画像は遅く読み込まれるため、画像は散在しています。これを解決する方法。 setTimeOutを使用したくありません。

サンプルコードは次のとおりです。

<!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>
11
Anirban Datta

# UPDATE [August 2017]

loadwindowの代わりにDOMContentLoadeddocumentイベントを処理できることを除いて、以下と同じ回答。これにより、window内のすべてのアセット(画像など)がloadedになります。

window.addEventListener("load", function(event) {
    ...
})

強制する必要はありませんAngular where Vanilla javascriptで十分です。これは私のAngularJSプロジェクトでどのように機能したかです

これをbodyタグに追加しました。HTMLコンテンツが読み込まれると、scriptタグで削除されます

<div id="page-loading">
    <img style="display:block; margin:0 auto;" src="styles/img/page-loading.gif">
</div>

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>

DOMContentLoadedeventは、callbackがすべてのimages,fonts,js and other assetsがロードされました。

幸運を。

17
Akash

これが正しいアプローチかどうかはわかりませんが、私が普段やっていることは、$scope.loadedページの状態を持つ変数。ページがロードされている場合は、表示するdivが表示されます...ロードされている場合は、ローダーを含むdivが表示されます。これを見てください plunk 私が言いたいことを得るために。

ここにもPlunkrコードを貼り付けています。

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 [〜#〜]

<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>

さらにサポートが必要な場合はお知らせください。

3
Haseeb Ahmed

これを試して:

angular.element($window).bind('load', function() {
 $scope.yourLoaderDiv=true;
});
1
vineet

@chotesahの答えはちょうどいいですが、別の方法で各画像にプリローダーを使用することをお勧めします(ページの読み込み時にFacebookのようなもの)。

これを試してください モジュール 。いくつかの行を変更する必要があります。

// 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]" />

その後、 codrops で気の利いた画像プリローダーを探します。

0
terales

それを達成するために、本文の最後にすべてのスクリプトをロードしています。 app-wrapper-divの前に、「loading」-divを修正した位置を配置します。他のスクリプトがロードされる直前に表示されます。

本文の最後に、スクリプトを含めた後、angularディレクティブを配置します。このディレクティブは、フェードアウトし、loading-divを削除します。

コード:

<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>

そして、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);
      }
    };
  });
})();
0
Ruwen

私は同じ問題に苦しんでいます。約束に基づいて異なるセクションごとに複数の読み込みイメージを表示している私の側で働いているものは次のとおりです。この目的のために、ディレクティブを作成しました。

私のhtmlは次のようになります。

<mi-loading promise="Loading"></mi-loading>

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>'
        };
    });

})();

そして最後に使用法、

 var getData = function ()
           {
               var Promise = myservice.getMyData($scope);

               $scope.Loading = Promise;
           };

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;
    }
0
J-D