Schritt 5: Bilder aus dem Web hinzufügen

In diesem Schritt lernen Sie:

  • Hier erfahren Sie, wie Sie Ressourcen von außerhalb Ihrer App laden und über XHR und ObjectURLs dem DOM hinzufügen.

Geschätzte Zeit für diesen Schritt: 20 Minuten
Wenn Sie eine Vorschau der Schritte in diesem Schritt sehen möchten, springen Sie zum Ende der Seite ↓.

Auswirkungen der CSP auf die Verwendung externer Ressourcen

Auf der Chrome Apps-Plattform muss Ihre App vollständig den Content Security Policy (CSP) entsprechen. Sie können DOM-Ressourcen wie Bilder, Schriftarten und CSS nicht direkt von außerhalb Ihres Chrome-App-Pakets laden.

Wenn Sie ein externes Bild in Ihrer Anwendung anzeigen möchten, müssen Sie es über XMLHttpRequest anfordern, es in ein Blob umwandeln und eine ObjectURL erstellen. Dieser ObjectURL kann dem DOM hinzugefügt werden, da er im Kontext der Anwendung auf ein speicherinternes Element verweist.

Miniaturansichten für Aufgaben anzeigen

Ändern wir nun unsere App so, dass sie in einem To-do-Element nach Bild-URLs sucht. Wenn die URL wie ein Bild aussieht, also z. B. auf .png, .jpg, .svg oder .gif endet, gehen Sie wie oben beschrieben vor, damit neben der URL eine Miniaturansicht angezeigt wird.

Berechtigungen aktualisieren

In einer Chrome-Anwendung können Sie XMLHttpRequest-Aufrufe an jede URL senden, solange Sie deren Domain im Manifest angeben. Da Sie vorher nicht wissen, welche Bild-URL der Nutzer eingeben wird, bitten Sie um die Berechtigung, Anfragen an "<all_urls>" zu stellen.

Fordern Sie in manifest.json die Berechtigung „“ an:

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

ObjectURLs erstellen und löschen

Fügen Sie in controller.js die Methode _createObjectURL() hinzu, um ObjectURLs aus einem Blob zu erstellen:

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

Objekt-URLs enthalten Arbeitsspeicher und sollten daher widerrufen werden, wenn Sie die ObjectURL nicht mehr benötigen. Fügen Sie controller.js diese _clearObjectURL()-Methode hinzu, um Folgendes zu verarbeiten:

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

XHR-Anfrage stellen

Fügen Sie die Methode _requestRemoteImageAndAppend() hinzu, um einen XMLHttpRequest für eine bestimmte Bild-URL auszuführen:

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();
};

Beim XHR-Laden erstellt diese Methode ein ObjectURL aus der XHR-Antwort und fügt dem DOM ein <img>-Element mit dieser ObjectURL hinzu.

Bild-URLs in Aufgaben parsen

Fügen Sie jetzt eine _parseForImageURLs()-Methode hinzu, die alle noch nicht verarbeiteten Links findet und auf Bilder prüft. Führen Sie für jede URL, die wie ein Bild aussieht, _requestRemoteImageAndAppend() aus:

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]);
    }
  }
};

Miniaturansichten in der Aufgabenliste rendern

Rufen Sie jetzt _parseForImageURLs() aus showAll(), showActive() und showCompleted() auf:

/**
 * 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));
};

Wiederholen Sie diesen Schritt für 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) {
  ...
}

Angezeigte Bildabmessungen einschränken

Fügen Sie schließlich in _bowercomponents/todomvc-common/base.css eine CSS-Regel hinzu, um die Größe des Bildes zu begrenzen:

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

Fertige Todo-App starten

Sie haben Schritt 5 abgeschlossen! Aktualisieren Sie Ihre App und fügen Sie eine Aufgabe mit einer URL zu einem online gehosteten Bild hinzu. Hier einige URLs, die Sie verwenden können: http://goo.gl/nqHMF#.jpg oder http://goo.gl/HPBGR#.png.

Weitere Informationen

Detailliertere Informationen zu einigen der in diesem Schritt vorgestellten APIs finden Sie unter:

Sind Sie bereit, mit dem nächsten Schritt fortzufahren? Gehen Sie zu Schritt 6: Aufgaben in das Dateisystem exportieren »