Подтвердить что ты не робот

Angularjs ждет, пока не появится фоновое изображение div

У меня есть следующий ng-repeat, который захватывает данные из вызова $http.post и сохраняет его в $scope.data.

<div ng-repeat="key in [] | range:data.pages">
    <div class="pageBackground" id="page_{{ (key+1) }}" ng-style="{'background-image':'url(/images/{{data.id}}/{{(key+1)}}.png)'}">
    <!-- some random stuff here -->
</div>

Что обычно происходит, класс .pageBackground будет загружаться до того, как фоновое изображение будет отображаться на экране. Я бы хотел, чтобы ничего не отображалось до тех пор, пока background-image не загрузится, но я не смог понять это.

Есть ли у кого-нибудь предложения?

4b9b3361

Ответ 1

Я не уверен, что есть реальное решение вашей проблемы. Обходным путем может быть использование Image объекта, как описано в этом ответе. Например, в качестве директивы:

angular.module("yourModule").directive("showOnceBackgroundLoaded", [function () {
  return {
    restrict: "A",
    scope: false,
    link: function (scope, element, attributes) {
      element.addClass("ng-hide");
      var image = new Image();
      image.onload = function () {
        // the image must have been cached by the browser, so it should load quickly
        scope.$apply(function () {
          element.css({ backgroundImage: 'url("' + attributes.showOnceBackgroundLoaded + '")' });
          element.removeClass("ng-hide");
        });
      };
      image.src = attributes.showOnceBackgroundLoaded;
    }
  };
}]);

Использование:

<div ng-repeat="key in [] | range:data.pages">
    <div class="pageBackground" id="page_{{ (key+1) }}" show-once-background-loaded="/images/{{data.id}}/{{(key+1)}}.png">
    <!-- some random stuff here -->
</div>

Ответ 2

Посмотрите здесь:

Как узнать, когда загружено фоновое изображение CSS? Событие запущено?

что вы делаете, вы создаете невидимый партнерский элемент, загружающий одно и то же изображение. если и только если это изображение было загружено (событие onload), вы показываете свой другой элемент, например, например:

<div ng-repeat="key in [] | range:data.pages" ng-init="_imageLoaded={}">
    <div ng-show="_imageLoaded[$index]" class="pageBackground" id="page_{{ (key+1) }}" ng-style="{'background-image':'url(/images/{{data.id}}/{{(key+1)}}.png)'}">
    <img ng-show="false" src="/images/{{data.id}}/{{(key+1)}}.png" onload="_imageLoaded[$index] = true;" />
    <!-- some random stuff here -->
</div>

Ответ 3

Вы можете задержать свою функцию запуска до загрузки изображения.

  var img = new Image();
  img.onload = function(){
    loadData();
  };
  img.src = 'https://mdn.mozillademos.org/files/5397/rhino.jpg';

Затем поместите ng-if="imageLoaded" в html и установите значение true в функции loadData.

Ответ 4

Вот директива, которая закладывает ваше изображение в качестве фона и ждет показ, пока изображение не загрузится. Вы можете включать переменные внутри параметра "mysrc", необходимые для генерации разных изображений (например, из ng-repeat).

angular.module('foo', [])
  .directive('myPageBackground', function() {
    return {
      scope: {
        key: '=', // used for ID of the element; if you set the ID externally to the directive you could omit this
        mysrc: '=' // used for the URL of the desired background image
      },
      template: '<div ng-show="showMe" class="pageBackground" id="page_{{key}}" ng-style="{\'background-image\':\'url({{mysrc}})\'}"></div>',
      link: function(scope) {
        var img = new Image();
        img.onload = function() {
          scope.showMe = true;
          scope.$apply();
        };
        img.src = scope.mysrc;
      }
    }
  });
.pageBackground {
  width: 200px; height: 200px;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="foo">
  <!-- Done with hardcoded values here, just for demo: -->
  <div my-page-background key="'1'" mysrc="'http://placehold.it/200x200'"></div>
  <div my-page-background key="'2'" mysrc="'http://placehold.it/150x150'"></div>
  <div my-page-background key="'3'" mysrc="'http://placehold.it/100x100'"></div>
</div>

Ответ 5

Если вы всегда используете один и тот же class="pageBackground", то фоновое изображение всегда одно и то же. Вы можете загрузить его в скрытое изображение, поэтому браузер кэширует его:

<img src="url" style="display:none;"/>

Или предварительно загрузите javascript на загрузку страницы:

var img = new Image();
img.src = 'some url';

Я считаю, что сообщение запускается с пользовательским взаимодействием, что происходит после загрузки страницы, поэтому изображение уже находится в браузере, и оно появляется сразу же после применения class="pageBackground"

Надеюсь, это поможет!

Ответ 6

Вы можете использовать ngSrc вместо div. Кроме того, вы можете попытаться использовать небольшую ленивую библиотеку изображений загрузки, такую ​​как ng-lazy-img.

Я надеюсь, что это поможет!

Ответ 7

Здесь показан полностью работоспособный пример с использованием объекта Image.

function AppCtrl($scope) {
  $scope.images = [{
    src: 'https://farm4.staticflickr.com/3261/2801924702_ffbdeda927_d.jpg'
  }, {
    src: 'https://farm9.staticflickr.com/8455/8048926748_1bc624e5c9_d.jpg'
  }];
  angular.forEach($scope.images, function(image) {
    var img = new Image();
    img.onload = function() {
      $scope.$apply(function() {
        image.loadedSrc = image.src;
      });
    };
    img.src = image.src;
  });
}
.hasSrc {
  color: purple;
  padding: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app>
  <div ng-controller="AppCtrl">
    <div ng-repeat="image in images" ng-class="{ hasSrc: !!image.loadedSrc }" style="background-image: url({{image.loadedSrc}})">
      <h2>THIS IS SOME TEXT BEING USED</h2>
      <p>
        This text is being used for illustration purposes only.
      </p>
    </div>
  </div>
</div>

Ответ 8

Вы можете получить помощь от angular promises. Если изображение загружено как обещано, то визуализируйте его еще иначе.

Вы уже проверили эту ссылку.

preloading-images-in-angularjs-with-promises

Спасибо