Проверка полной загрузки изображения в AngularJS: ng-src и iScroll

Пройдите тест, узнайте какой профессии подходите и получите бесплатную карьерную консультацию
В конце подарим скидку до 55% на обучение
Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

В AngularJS существует директива, предназначенная для отслеживания момента окончания загрузки изображения с использованием ng-src. Необходимо назначить событие load для элемента img вот таким образом:

JS
Скопировать код
app.directive('imageOnLoad', function() {
  return {
    restrict: 'A',
    link: function(scope, element) {
      element.on('load', function() {
        // Изображение загружено, отмечаем это событие!
        scope.$evalAsync('whenLoaded()');
        
        element.on('error', function() {
          // Произошла ошибка во время загрузки изображения, день не задался...
          scope.$evalAsync('onLoadFailed()');
        });
      });
    }
  };
});

Для использования этой директивы в HTML следует сделать так:

HTML
Скопировать код
<img ng-src="{{imageUrl}}" image-on-load>

Замените whenLoaded() и onLoadFailed() на соответствующие функции, которые вы планируете вызывать в случае успешной или неудачной загрузки изображения.

iScroll – Предотвращение нежелательного скроллинга

Если изображение расположено в скроллируемом контейнере, например, в iScroll, обновление скроллера сразу после загрузки изображения обеспечит пользователям гладкий скроллинг. Это также поможет правильно определить границы прокрутки:

JS
Скопировать код
app.controller('MyController', function($scope) {
  $scope.whenLoaded = function() {
    if (iScrollInstance) {
      // Подготовка завершена, iScroll может обновиться
      iScrollInstance.refresh();
    }
  };
});

Функция iScrollInstance.refresh() вызывается каждый раз, когда успешно завершается загрузка изображения.

Упс, что теперь? Обработка ошибок загрузки изображений

Чтобы ваша директива загрузки изображений в AngularJS была надежной, добавьте обработку исключительных ситуаций для случаев, когда загрузка изображений не происходит:

JS
Скопировать код
app.directive('imageOnLoad', function() {
  return {
    restrict: 'A',
    link: function(scope, element) {
      element.on('load', function() {
        // Все прекрасно, изображение успешно загружено!
        scope.$evalAsync('whenLoaded()');
      }).on('error', function() {
        // Необходимо решить проблему с загрузкой изображения
        scope.$evalAsync('onLoadFailed()');
      });
    }
  };
});

В случае, если загрузка изображения не может быть выполнена, задайте альтернативное изображение или сообщение, определив соответствующую функцию onLoadFailed().

Многофункциональная директива: расширенное использование

Сделайте директиву более эффективной, позволив передачу изменчивых callback-функций:

JS
Скопировать код
app.directive('imageOnLoad', function() {
  return {
    scope: {
      whenLoaded: '&', // Динамический коллбэк для успешной загрузки
      onLoadFailed: '&' // Динамический коллбэк для обработки ошибок
    },
    link: function(scope, element, attrs) {
      element.on('load', function() {
        // Изображение загружено как по учебнику!
        scope.whenLoaded();
      }).on('error', function() {
        // Возникла проблема: изображение не загружено!
        scope.onLoadFailed();
      });
    }
  };
});

Привязка callback-функций к области видимости (scope) делает директиву гибкой и позволяет назначать разные функции для разных тегов <img>:

HTML
Скопировать код
<img ng-src="{{imageUrl}}" image-on-load when-loaded="imageLoaded()" 
on-load-failed="imageLoadFailed()">

Визуализация

Представим, как работает загрузка изображения при помощи простой аналогии:

Markdown
Скопировать код
🚂 = Изображение
🛤️ = путь ng-src
🚉 = HTML-элемент (где установлен ng-src)

Путешествие поезда:

Markdown
Скопировать код
1. Поезд (🚂) отправляется по рельсам (🛤️) к станции (🚉).
2. Пассажиры (👀) ожидают его прибытия.
3. По прибытии поезда (загрузка изображения завершена) пассажиры начинают свое путешествие (срабатывает событие).

В контексте AngularJS это выглядит следующим образом:

JS
Скопировать код
$scope.$watch('imageUrl', function (newValue) {
    if (newValue) {
        // 🚂 достигает 🚉 по 🛤️
        // Дается сигнал пассажирам (срабатывает событие)
    }
});

Итог: Как только изображение полностью загружено (поезд прибыл), событие срабатывает (объявляется о прибытии).

Полезные материалы

  1. AngularJS API Docs – ngSrc Directiveофициальная документация по директиве ngSrc в AngularJS.
  2. MDN Web Docs – EventTarget.addEventListener() — руководство по использованию addEventListener() в JavaScript.
  3. CSS-Tricks – Fixing .load() in IE for Cached Images — потенциальные слабые места и способы их устранения при работе со событиями загрузки изображений в браузере Internet Explorer.
  4. AngularJS API Docs – ngBind Directive — официальная документация по директиве ngBind для AngularJS.
  5. HTML Standard – img: The Image elementспецификация HTML разъясняет работу элемента <img> и связанное с ним поведение загрузки.
  6. GitHub – angular/ngImgCrop: Image Crop Directive for AngularJSдиректива для обрезки изображений в AngularJS, демонстрирующая различные возможности управления ng-src.