0

I have an app in Ionic v.1 and on page where I have a list of articles, I would like to have a splash screen until the first image is completely loaded, not sure how to do that?

This is the controller:

module.exports = angular.module('coop.controllers')
.controller('ArticlesController', function($scope, ArticleService, $state, $ionicScrollDelegate, $location, $ionicPosition, $ionicConfig) {
  $scope.articles = ArticleService.all();

  $scope.$on('$ionicParentView.afterEnter', function(event, data) {
    $scope.videoPlaying = [];
    $ionicConfig.views.swipeBackEnabled(false);

    if (data.direction == 'back') {
      $scope.doRefresh();
    }
  });

  $scope.articleType = 'all';

  $scope.articleFilter = function(button) {
    $scope.articleType = button;

    $scope.doRefresh();
  };

  $scope.showBulletPoint = function(which) {
    return $scope.articleType == which;
  }

  $scope.like = function(article){
    article.userLiked = !article.userLiked;
    ArticleService.like(article)
  };

  $scope.doRefresh = function (){
    var articleType = $scope.articleType ? $scope.articleType : 'all';

    ArticleService[articleType]().$promise.then(function(data){
       $scope.articles = data;
    }).finally(function() {
       $scope.$broadcast('scroll.refreshComplete');
    });
  };

  $scope.videoPlaying = [];
  $scope.playerVars = {
    controls: 0,
    showinfo: 0
  };

  $scope.playVideo = function(youtubePlayer, index) {
    $scope.videoPlaying[index] = true;
    youtubePlayer.playVideo();
  };

  $scope.$on('$ionicView.afterLeave', function(event, data) {
      $scope.videoPlaying = false;
      $ionicConfig.views.swipeBackEnabled(true);
      //youtubePlayer.stopVideo();
  });
});

And this the html:

<ion-view>
  <div class="row articles-header">
    <button menu-toggle="left" class="button button-icon icon ion-navicon-round"></button>
    <div class="right-icons">
      <!--<a class="button button-icon icon ion-ios-search-strong">
      </a>-->
      <a class="button button-icon" href="#" ng-click="articleFilter('all')"><i class="ion-ios-circle-filled" ng-show="showBulletPoint('all')"></i> Siste
      </a>
      <a class="button button-icon" href="#" ng-click="articleFilter('video')"><i class="ion-ios-circle-filled" ng-show="showBulletPoint('video')"></i> Video
      </a>
      <a class="button button-icon" href="#" ng-click="articleFilter('popular')"><i class="ion-ios-circle-filled" ng-show="showBulletPoint('popular')"></i> Populært
      </a>
    </div>
  </div>

  <ion-content class="articles-content">
    <ion-refresher pulling-icon="false" on-refresh="doRefresh()">
    </ion-refresher>
    <ion-list>
      <ion-item ng-repeat="article in articles" class="item-light">
        <div class="article">
          <a ng-if="authenticated" ng-show="article.external_media.length == 0"  ui-sref="main.article({id: article.id})" nav-direction="forward" class="article-image-link">
            <img class="img" src="{{ fileServer }}/imagecache/cover/{{article.cover_image}}">
            <h1>{{ article.title.split(' ', 7).join(' ') }}</h1>
          </a>
          <a ng-if="!authenticated" ng-show="article.external_media.length == 0"  ui-sref="main.articlePublic({id: article.id})" nav-direction="forward" class="article-image-link">
            <img class="img" src="{{ fileServer }}/imagecache/cover/{{article.cover_image}}">
            <h1>{{ article.title.split(' ', 7).join(' ') }}</h1>
          </a>
          <a ui-sref="main.article({id: article.id})">
            <div class="iframe" ng-show="article.external_media.length > 0 && article.external_media.image != ''">
              <img class="img" ng-src="{{ article.external_media[0].image }}">
              <h1>{{ article.title.split(' ', 7).join(' ') }}</h1>
              <div class="iframe-overlay">
                <div class="play">
                  <img class="playButton" src="icons/playRectangle.svg"/>
                </div>
              </div>
            </div>
          </a>
        </div>

        <div class="row article-meta" ng-class="{ 'has-comments': article.enable_comments }">
          <a ng-click="like(article)" class="subdued col col-30">
            <img class="social-images" ng-src="icons/{{ article.userLiked ? 'heart' : 'heart-outline' }}.svg"/> Lik
          </a>
          <a ui-sref="main.article({id: article.id, gotoComments: true })" class="subdued col col-60" ng-if="article.enable_comments">
            <img class="social-images" src="icons/comment.svg"/> {{ article.commentCount }} Kommentarer
          </a>
          <a ui-sref="main.article({id: article.id})" nav-direction="forward" class="col col-10 article-link right">
            <img class="social-images" src="icons/arrow.svg"/>
          </a>
        </div>

      </ion-item>
    </ion-list>
  </ion-content>
</ion-view>
Ludwig
  • 1,401
  • 13
  • 62
  • 125

1 Answers1

1

One approach is to attach an onLoad handler to the images, and when the first image (or any other specific image, all, etc) have loaded you can remove your splash screen.

To do this we'll create a directive to handle the onload event, based on this outstanding solution from Peter, combined with the $ionicLoading loader.

var app = angular.module('app', ['ionic'])

app.controller('appCtrl', function($scope, $timeout, $ionicLoading) {

  // Setup the loader
  $ionicLoading.show({
    content: 'Loading',
    animation: 'fade-in',
    showBackdrop: true,
    maxWidth: 200,
    showDelay: 0 
  });

  // Add a simple onLoad callback
  $scope.onLoad = function (id) {
    if (id === 0) {
      $ionicLoading.hide();
    }
  }

  $scope.items = [
    {img: 'http://placehold.it/5000x8000/f9009a/ffffff'}, 
    {img: 'http://placehold.it/5000x8000/f9009a/ffffff'}, 
    {img: 'http://placehold.it/5000x8000/f9009a/ffffff'}
  ];

});

// The imageonload directive
app.directive('imageonload', function() {
  return {
    restrict: 'A',
    link: function(scope, element, attrs) {
      element.bind('load', function() {
        //call the function that was passed
        scope.$apply(attrs.imageonload);
      });
    }
  };
})

Then use the directive:

<ion-item ng-repeat="item in items" href="#">
  <img ng-src="{{item.img}}" imageonload="onLoad({{$index}})" id="img-{{$index}}" />
</ion-item>

When the app loads the $ionicLoading screen will be shown until the first image emits the onload event, causing the $ionicLoading screen to be removed.

For a working demo, see this Ionic Play demo.

The loading screen may only be noticeable the first time you load the demo, and on subsequent loads you might need to do a hard refresh.

Community
  • 1
  • 1
Brett DeWoody
  • 59,771
  • 29
  • 135
  • 184