LoginSignup
3
1

More than 5 years have passed since last update.

[monaca]ui-router遷移時にローディング処理を入れてみた。

Last updated at Posted at 2017-09-21

ui-routerで遷移する際に、ローディング(くるくる回るやつ)を入れてみました。

ベース

onsenui, angularjs, ui-router が使える状態の最小限プロジェクト
[monaca][onsenui][AngularJS][ui-router]onsenui/ui-router最小限プロジェクト

html

index.html
<!DOCTYPE HTML>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
  <meta http-equiv="Content-Security-Policy" content="default-src * data: gap: https://ssl.gstatic.com; style-src * 'unsafe-inline'; script-src * 'unsafe-inline' 'unsafe-eval'">
  <script src="components/loader.js"></script>
  <script src="script.js"></script>

  <link rel="stylesheet" href="components/loader.css">
  <link rel="stylesheet" href="css/style.css">
</head>
<body ng-app="MyApp">

    <ons-page>
        <ons-toolbar>
            <div class="center">Loading</div>
        </ons-toolbar>

        <div ng-controller="LoadingController">
            <ons-button ng-click="changePage('page-A')">pageA</ons-button>
            <ons-button ng-click="changePage('page-B')">pageB</ons-button>

            <div style="padding: 20px 10px;" ui-view></div>

            <my-loader></my-loader>
        </div>

        <script id="pageA.html" type="text/ng-template">
            <div style="background-color: #FFCCCC; padding: 10px;">pageAだよ</div>
        </script>
        <script id="pageB.html" type="text/ng-template">
            <div style="background-color: #CCCCFF; padding: 10px;">pageBだよ</div>
        </script>

    </ons-page>

    <ons-template id="loader.html">
        <div ng-if="$root.isLoading" class="loader-parent"><div class="loader">Loading...</div></div>
    </ons-template>
</body> 
</html>

javascript

script.js
var myApp = angular.module('MyApp', ['onsen', 'ui.router']);

// 遷移処理
myApp.config(['$stateProvider', '$urlRouterProvider', function($stateProvider, $urlRouterProvider) {

        $stateProvider
            .state('page-A', {
                url: '/pageA',
                templateUrl: 'pageA.html'
            })
            .state('page-B', {
                url: '/pageB',
                templateUrl: 'pageB.html'
            })

    }]);

// ボタン押下時の処理
myApp.controller('LoadingController', ['$scope', '$state', '$rootScope', '$timeout', function($scope, $state, $rootScope, $timeout) {
        $scope.changePage = function(page) {
            // ローディングフラグON
            $rootScope.isLoading = true;

            // 2秒待ってから遷移する
            $timeout(function() {
                $state.go(page);
            }, 2000);
        }
    }]);

// ローディングタグ
myApp.directive('myLoader', function() {
        return {
            restrict : 'E',
            replace: true,
            templateUrl: "loader.html"
        };
    }); 


// 画面遷移タイミング処理
myApp.run(['$rootScope', '$transitions', '$state', function($rootScope, $transitions, $state){
    $transitions.onSuccess({to:'*'}, function(trans){
        // ページ読み込み成功

        // ローディングフラグOFF
        $rootScope.isLoading = false;
    });

}]);

css

style.css

div.loader-parent {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    margin: auto;
    height: 200px;
    width: 200px;
}
.loader {
  margin: 80px auto;
  font-size: 25px;
  width: 1em;
  height: 1em;
  border-radius: 50%;
  position: relative;
  text-indent: -9999em;
  -webkit-animation: load5 1.1s infinite ease;
  animation: load5 1.1s infinite ease;
  -webkit-transform: translateZ(0);
  -ms-transform: translateZ(0);
  transform: translateZ(0);
}
@-webkit-keyframes load5 {
  0%,
  100% {
    box-shadow: 0em -2.6em 0em 0em #7f7f7f, 1.8em -1.8em 0 0em rgba(127,127,127, 0.2), 2.5em 0em 0 0em rgba(127,127,127, 0.2), 1.75em 1.75em 0 0em rgba(127,127,127, 0.2), 0em 2.5em 0 0em rgba(127,127,127, 0.2), -1.8em 1.8em 0 0em rgba(127,127,127, 0.2), -2.6em 0em 0 0em rgba(127,127,127, 0.5), -1.8em -1.8em 0 0em rgba(127,127,127, 0.7);
  }
  12.5% {
    box-shadow: 0em -2.6em 0em 0em rgba(127,127,127, 0.7), 1.8em -1.8em 0 0em #7f7f7f, 2.5em 0em 0 0em rgba(127,127,127, 0.2), 1.75em 1.75em 0 0em rgba(127,127,127, 0.2), 0em 2.5em 0 0em rgba(127,127,127, 0.2), -1.8em 1.8em 0 0em rgba(127,127,127, 0.2), -2.6em 0em 0 0em rgba(127,127,127, 0.2), -1.8em -1.8em 0 0em rgba(127,127,127, 0.5);
  }
  25% {
    box-shadow: 0em -2.6em 0em 0em rgba(127,127,127, 0.5), 1.8em -1.8em 0 0em rgba(127,127,127, 0.7), 2.5em 0em 0 0em #7f7f7f, 1.75em 1.75em 0 0em rgba(127,127,127, 0.2), 0em 2.5em 0 0em rgba(127,127,127, 0.2), -1.8em 1.8em 0 0em rgba(127,127,127, 0.2), -2.6em 0em 0 0em rgba(127,127,127, 0.2), -1.8em -1.8em 0 0em rgba(127,127,127, 0.2);
  }
  37.5% {
    box-shadow: 0em -2.6em 0em 0em rgba(127,127,127, 0.2), 1.8em -1.8em 0 0em rgba(127,127,127, 0.5), 2.5em 0em 0 0em rgba(127,127,127, 0.7), 1.75em 1.75em 0 0em #7f7f7f, 0em 2.5em 0 0em rgba(127,127,127, 0.2), -1.8em 1.8em 0 0em rgba(127,127,127, 0.2), -2.6em 0em 0 0em rgba(127,127,127, 0.2), -1.8em -1.8em 0 0em rgba(127,127,127, 0.2);
  }
  50% {
    box-shadow: 0em -2.6em 0em 0em rgba(127,127,127, 0.2), 1.8em -1.8em 0 0em rgba(127,127,127, 0.2), 2.5em 0em 0 0em rgba(127,127,127, 0.5), 1.75em 1.75em 0 0em rgba(127,127,127, 0.7), 0em 2.5em 0 0em #7f7f7f, -1.8em 1.8em 0 0em rgba(127,127,127, 0.2), -2.6em 0em 0 0em rgba(127,127,127, 0.2), -1.8em -1.8em 0 0em rgba(127,127,127, 0.2);
  }
  62.5% {
    box-shadow: 0em -2.6em 0em 0em rgba(127,127,127, 0.2), 1.8em -1.8em 0 0em rgba(127,127,127, 0.2), 2.5em 0em 0 0em rgba(127,127,127, 0.2), 1.75em 1.75em 0 0em rgba(127,127,127, 0.5), 0em 2.5em 0 0em rgba(127,127,127, 0.7), -1.8em 1.8em 0 0em #7f7f7f, -2.6em 0em 0 0em rgba(127,127,127, 0.2), -1.8em -1.8em 0 0em rgba(127,127,127, 0.2);
  }
  75% {
    box-shadow: 0em -2.6em 0em 0em rgba(127,127,127, 0.2), 1.8em -1.8em 0 0em rgba(127,127,127, 0.2), 2.5em 0em 0 0em rgba(127,127,127, 0.2), 1.75em 1.75em 0 0em rgba(127,127,127, 0.2), 0em 2.5em 0 0em rgba(127,127,127, 0.5), -1.8em 1.8em 0 0em rgba(127,127,127, 0.7), -2.6em 0em 0 0em #7f7f7f, -1.8em -1.8em 0 0em rgba(127,127,127, 0.2);
  }
  87.5% {
    box-shadow: 0em -2.6em 0em 0em rgba(127,127,127, 0.2), 1.8em -1.8em 0 0em rgba(127,127,127, 0.2), 2.5em 0em 0 0em rgba(127,127,127, 0.2), 1.75em 1.75em 0 0em rgba(127,127,127, 0.2), 0em 2.5em 0 0em rgba(127,127,127, 0.2), -1.8em 1.8em 0 0em rgba(127,127,127, 0.5), -2.6em 0em 0 0em rgba(127,127,127, 0.7), -1.8em -1.8em 0 0em #7f7f7f;
  }
}
@keyframes load5 {
  0%,
  100% {
    box-shadow: 0em -2.6em 0em 0em #7f7f7f, 1.8em -1.8em 0 0em rgba(127,127,127, 0.2), 2.5em 0em 0 0em rgba(127,127,127, 0.2), 1.75em 1.75em 0 0em rgba(127,127,127, 0.2), 0em 2.5em 0 0em rgba(127,127,127, 0.2), -1.8em 1.8em 0 0em rgba(127,127,127, 0.2), -2.6em 0em 0 0em rgba(127,127,127, 0.5), -1.8em -1.8em 0 0em rgba(127,127,127, 0.7);
  }
  12.5% {
    box-shadow: 0em -2.6em 0em 0em rgba(127,127,127, 0.7), 1.8em -1.8em 0 0em #7f7f7f, 2.5em 0em 0 0em rgba(127,127,127, 0.2), 1.75em 1.75em 0 0em rgba(127,127,127, 0.2), 0em 2.5em 0 0em rgba(127,127,127, 0.2), -1.8em 1.8em 0 0em rgba(127,127,127, 0.2), -2.6em 0em 0 0em rgba(127,127,127, 0.2), -1.8em -1.8em 0 0em rgba(127,127,127, 0.5);
  }
  25% {
    box-shadow: 0em -2.6em 0em 0em rgba(127,127,127, 0.5), 1.8em -1.8em 0 0em rgba(127,127,127, 0.7), 2.5em 0em 0 0em #7f7f7f, 1.75em 1.75em 0 0em rgba(127,127,127, 0.2), 0em 2.5em 0 0em rgba(127,127,127, 0.2), -1.8em 1.8em 0 0em rgba(127,127,127, 0.2), -2.6em 0em 0 0em rgba(127,127,127, 0.2), -1.8em -1.8em 0 0em rgba(127,127,127, 0.2);
  }
  37.5% {
    box-shadow: 0em -2.6em 0em 0em rgba(127,127,127, 0.2), 1.8em -1.8em 0 0em rgba(127,127,127, 0.5), 2.5em 0em 0 0em rgba(127,127,127, 0.7), 1.75em 1.75em 0 0em #7f7f7f, 0em 2.5em 0 0em rgba(127,127,127, 0.2), -1.8em 1.8em 0 0em rgba(127,127,127, 0.2), -2.6em 0em 0 0em rgba(127,127,127, 0.2), -1.8em -1.8em 0 0em rgba(127,127,127, 0.2);
  }
  50% {
    box-shadow: 0em -2.6em 0em 0em rgba(127,127,127, 0.2), 1.8em -1.8em 0 0em rgba(127,127,127, 0.2), 2.5em 0em 0 0em rgba(127,127,127, 0.5), 1.75em 1.75em 0 0em rgba(127,127,127, 0.7), 0em 2.5em 0 0em #7f7f7f, -1.8em 1.8em 0 0em rgba(127,127,127, 0.2), -2.6em 0em 0 0em rgba(127,127,127, 0.2), -1.8em -1.8em 0 0em rgba(127,127,127, 0.2);
  }
  62.5% {
    box-shadow: 0em -2.6em 0em 0em rgba(127,127,127, 0.2), 1.8em -1.8em 0 0em rgba(127,127,127, 0.2), 2.5em 0em 0 0em rgba(127,127,127, 0.2), 1.75em 1.75em 0 0em rgba(127,127,127, 0.5), 0em 2.5em 0 0em rgba(127,127,127, 0.7), -1.8em 1.8em 0 0em #7f7f7f, -2.6em 0em 0 0em rgba(127,127,127, 0.2), -1.8em -1.8em 0 0em rgba(127,127,127, 0.2);
  }
  75% {
    box-shadow: 0em -2.6em 0em 0em rgba(127,127,127, 0.2), 1.8em -1.8em 0 0em rgba(127,127,127, 0.2), 2.5em 0em 0 0em rgba(127,127,127, 0.2), 1.75em 1.75em 0 0em rgba(127,127,127, 0.2), 0em 2.5em 0 0em rgba(127,127,127, 0.5), -1.8em 1.8em 0 0em rgba(127,127,127, 0.7), -2.6em 0em 0 0em #7f7f7f, -1.8em -1.8em 0 0em rgba(127,127,127, 0.2);
  }
  87.5% {
    box-shadow: 0em -2.6em 0em 0em rgba(127,127,127, 0.2), 1.8em -1.8em 0 0em rgba(127,127,127, 0.2), 2.5em 0em 0 0em rgba(127,127,127, 0.2), 1.75em 1.75em 0 0em rgba(127,127,127, 0.2), 0em 2.5em 0 0em rgba(127,127,127, 0.2), -1.8em 1.8em 0 0em rgba(127,127,127, 0.5), -2.6em 0em 0 0em rgba(127,127,127, 0.7), -1.8em -1.8em 0 0em #7f7f7f;
  }
}

引用元)Single Element CSS Spinners

画面イメージ

loading12.png

処理の流れ

  1. ボタン押下
  2. $scope.changePage が実行される
    1. $rootScope.isLoading = true を設定する
    2. <my-loader>内のdivタグにかかってるng-if="$root.isLoading"がヒットし、divタグが表示される
    3. cssのアニメーション処理でローディングがくるくる回る
  3. $timeout で2秒後に $state.go(遷移処理)が実行される
  4. ui-viewの読み込みが完了すると、$transitions.onSuccess が実行される
    1. $rootScope.isLoading = false を設定する
    2. ローディングが非表示になる

ソースコード

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1