Schritt 5: Bilder aus dem Web hinzufügen

In diesem Schritt erfahren Sie:

  • Informationen zum Laden von Ressourcen von außerhalb Ihrer App und zum Hinzufügen zum DOM über XHR und ObjectURLs.

Geschätzte Dauer für diesen Schritt: 20 Minuten.
Um eine Vorschau zu sehen, was Sie in diesem Schritt tun werden, springen Sie zum Ende dieser Seite ↓.

Wie die CSP die Nutzung externer Ressourcen beeinflusst

Die Chrome-Apps-Plattform erzwingt die vollständige Compliance Ihrer App mit den Content Security Policies (CSP). Sie können DOM-Ressourcen wie Bilder, Schriftarten und CSS nicht direkt von außerhalb Ihrer Chrome-App laden Paket.

Wenn Sie ein externes Bild in Ihrer App anzeigen möchten, müssen Sie es über XMLHttpRequest anfordern, in ein Blob transformieren und eine ObjectURL erstellen. ObjectURL kann hinzugefügt werden zu DOM, da es sich im Kontext der App auf ein speicherinternes Element bezieht.

Miniaturansichten für Aufgaben anzeigen

Jetzt ändern wir unsere App so, dass in einer Aufgabe nach Bild-URLs gesucht wird. Wenn die URL wie ein Bild aussieht (für z. B. auf .png, .jpg, .svg oder .gif endet, können Sie wie oben beschrieben vorgehen, Miniaturansicht neben der URL.

Berechtigungen aktualisieren

In einer Chrome-App können Sie XMLHttpRequest-Aufrufe an beliebige URLs senden, solange Sie deren Domain in des Manifests. Da Sie nicht im Voraus wissen, welche Bild-URL der Nutzer eingibt, fragen Sie nach der Berechtigung, Anfragen an "<all_urls>" senden

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

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

Objekt-URLs erstellen und löschen

Fügen Sie in controller.js eine _createObjectURL()-Methode hinzu, um Objekt-URLs 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. Wenn Sie die ObjectURL nicht mehr benötigen, sollten Sie sie widerrufen. Dieses Element hinzufügen _clearObjectURL()-Methode in controller.js, um dies 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 eine _requestRemoteImageAndAppend()-Methode hinzu, um eine XMLHttpRequest-Anfrage 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-Ladevorgang erstellt diese Methode ein ObjectURL aus der XHR-Antwort und fügt ein <img>-Element hinzu mit diesem ObjectURL zum DOM.

Nach Bild-URLs in To-do-Elementen parsen

Fügen Sie nun eine _parseForImageURLs()-Methode hinzu, die alle noch nicht verarbeiteten Links sucht und sie auf Bilder. 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() über 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));
};

Wiederhole den Vorgang 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) {
  ...
}

Abmessungen des angezeigten Bilds einschränken

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

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

Fertige To-do-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. Einige Mögliche URLs: http://goo.gl/nqHMF#.jpg oder http://goo.gl/HPBGR#.png

Weitere Informationen

Ausführlichere Informationen zu einigen der in diesem Schritt vorgestellten APIs finden Sie hier:

Sind Sie bereit für den nächsten Schritt? Gehen Sie zu Schritt 6 – Aufgaben in das Dateisystem exportieren.