Шаг 5. Добавьте изображения из Интернета

На этом этапе вы узнаете:

  • Как загружать ресурсы извне вашего приложения и добавлять их в DOM через XHR и ObjectURL.

Примерное время выполнения этого шага: 20 минут.
Чтобы просмотреть то, что вы выполните на этом этапе, прыгните вниз этой страницы ↓ .

Как CSP влияет на использование внешних ресурсов

Платформа Chrome Apps обеспечивает полное соответствие вашего приложения политикам безопасности контента (CSP). Вы не можете загружать ресурсы DOM, такие как изображения, шрифты и CSS, напрямую из-за пределов пакета приложения Chrome.

Если вы хотите показать внешнее изображение в своем приложении, вам необходимо запросить его через XMLHttpRequest , преобразовать его в Blob и создать ObjectURL . Этот ObjectURL можно добавить в DOM, поскольку он ссылается на элемент в памяти в контексте приложения.

Показывать миниатюры для элементов задач

Давайте изменим наше приложение, чтобы оно искало URL-адреса изображений в списке дел. Если URL-адрес выглядит как изображение (например, заканчивается на .png, .jpg, .svg или .gif), примените описанный выше процесс, чтобы отобразить миниатюру изображения рядом с URL-адресом.

Обновить разрешения

В приложении Chrome вы можете выполнять вызовы XMLHttpRequest к любому URL-адресу, если вы указываете его домен в манифесте. Поскольку вы заранее не знаете, какой URL-адрес изображения введет пользователь, запросите разрешение на отправку запросов к "<all_urls>" .

В файле Manifest.json запросите " " разрешение:

"permissions": ["storage", "alarms", "notifications",
                "webview", "<all_urls>"],

Создание и очистка ObjectURL

В контроллере.js добавьте метод _createObjectURL() для создания URL-адресов ObjectURL из Blob:

Controller.prototype._createObjectURL = function(blob) {
  var objURL = URL.createObjectURL(blob);
  this.objectURLs = this.objectURLs || [];
  this.objectURLs.push(objURL);
  return objURL;
};

ObjectURL хранят память, поэтому, когда ObjectURL вам больше не нужен, вам следует отозвать их. Добавьте этот метод _clearObjectURL() в контроллер.js, чтобы справиться с этим:

Controller.prototype._clearObjectURL = function() {
  if (this.objectURLs) {
    this.objectURLs.forEach(function(objURL) {
      URL.revokeObjectURL(objURL);
    });
    this.objectURLs = null;
  }
};

Сделать запрос XHR

Добавьте метод _requestRemoteImageAndAppend() для выполнения XMLHttpRequest по заданному URL-адресу изображения:

Controller.prototype._requestRemoteImageAndAppend = function(imageUrl, element) {
  var xhr = new XMLHttpRequest();
  xhr.open('GET', imageUrl);
  xhr.responseType = 'blob';
  xhr.onload = function() {
    var img = document.createElement('img');
    img.setAttribute('data-src', imageUrl);
    img.className = 'icon';
    var objURL = this._createObjectURL(xhr.response);
    img.setAttribute('src', objURL);
    element.appendChild(img);
  }.bind(this);
  xhr.send();
};

При загрузке XHR этот метод создает ObjectURL из ответа XHR и добавляет элемент <img> с этим ObjectURL в DOM.

Анализ URL-адресов изображений в задачах

Теперь добавьте метод _parseForImageURLs() , который находит все еще не обработанные ссылки и проверяет их на наличие изображений. Для каждого URL-адреса, который выглядит как изображение, выполните _requestRemoteImageAndAppend() :

Controller.prototype._parseForImageURLs = function () {
  // remove old blobs to avoid memory leak:
  this._clearObjectURL();
  var links = this.$todoList.querySelectorAll('a[data-src]:not(.thumbnail)');
  var re = /\.(png|jpg|jpeg|svg|gif)$/;
  for (var i = 0; i<links.length; i++) {
    var url = links[i].getAttribute('data-src');
    if (re.test(url)) {
      links[i].classList.add('thumbnail');
      this._requestRemoteImageAndAppend(url, links[i]);
    }
  }
};

Отображение миниатюр в списке задач

Теперь вызовите _parseForImageURLs() из showAll() , showActive() и showCompleted() :

/**
 * An event to fire on load. Will get all items and display them in the
 * todo-list
 */
Controller.prototype.showAll = function () {
  this.model.read(function (data) {
    this.$todoList.innerHTML = this._parseForURLs(this.view.show(data));
    this._parseForImageURLs();
  }.bind(this));
};

/**
 * Renders all active tasks
 */
Controller.prototype.showActive = function () {
  this.model.read({ completed: 0 }, function (data) {
    this.$todoList.innerHTML = this._parseForURLs(this.view.show(data));
    this._parseForImageURLs();
  }.bind(this));
};

/**
 * Renders all completed tasks
 */
Controller.prototype.showCompleted = function () {
  this.model.read({ completed: 1 }, function (data) {
    this.$todoList.innerHTML = this._parseForURLs(this.view.show(data));
    this._parseForImageURLs();
  }.bind(this));
};

Сделайте то же самое для editItem() :

Controller.prototype.editItem = function (id, label) {
  ...
  var onSaveHandler = function () {
    ...
    if (value.length && !discarding) {
      ...
      label.innerHTML = this._parseForURLs(value);
      this._parseForImageURLs();
    } else if (value.length === 0) {
  ...
}

Ограничить размеры отображаемого изображения

Наконец, в _bowerComponents/todomvc-common/base.css добавьте правило CSS, ограничивающее размер изображения:

.thumbnail img[data-src] {
  max-width: 100px;
  max-height: 28px;
}

Запустите готовое приложение Todo.

Вы закончили Шаг 5! Перезагрузите приложение и добавьте элемент задачи с URL-адресом к изображению, размещенному в Интернете. Некоторые URL-адреса, которые вы можете использовать: http://goo.gl/nqHMF#.jpg или http://goo.gl/HPBGR#.png .

Для получения дополнительной информации

Более подробную информацию о некоторых API, представленных на этом этапе, см.:

Готовы перейти к следующему шагу? Перейдите к шагу 6. ​​Экспорт задач в файловую систему »