Stap 5: Afbeeldingen van internet toevoegen

In deze stap leer je:

  • Hoe u bronnen van buiten uw app kunt laden en deze aan de DOM kunt toevoegen via XHR en ObjectURL's.

Geschatte tijd om deze stap te voltooien: 20 minuten.
Om een ​​voorbeeld te zien van wat u in deze stap gaat voltooien, springt u naar de onderkant van deze pagina ↓ .

Hoe CSP het gebruik van externe bronnen beïnvloedt

Het Chrome Apps-platform dwingt uw app om volledig te voldoen aan het Content Security Policies (CSP). U kunt DOM-bronnen zoals afbeeldingen, lettertypen en CSS niet rechtstreeks laden van buiten uw Chrome App-pakket.

Als u een externe afbeelding in uw app wilt weergeven, moet u deze aanvragen via XMLHttpRequest , deze omzetten in een Blob en een ObjectURL maken. Deze ObjectURL kan aan de DOM worden toegevoegd omdat deze verwijst naar een in-memory item in de context van de app.

Toon miniatuurafbeeldingen voor taken

Laten we onze app wijzigen om te zoeken naar afbeeldings-URL's in een takenlijst. Als de URL op een afbeelding lijkt (bijvoorbeeld eindigend op .png, .jpg, .svg of .gif), pas dan het bovengenoemde proces toe om een ​​miniatuur van de afbeelding naast de URL weer te geven.

Machtigingen bijwerken

In een Chrome-app kunt u XMLHttpRequest-aanroepen naar elke URL uitvoeren, zolang u het domein ervan in het manifest opgeeft. Omdat u van tevoren niet weet welke afbeeldings-URL de gebruiker zal typen, vraagt ​​u toestemming om verzoeken in te dienen bij "<all_urls>" .

Vraag in manifest.json de " " toestemming:

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

ObjectURL's maken en wissen

Voeg in controller.js een _createObjectURL() -methode toe om ObjectURL's van een BLOB te maken:

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

ObjectURL's bevatten geheugen, dus als u de ObjectURL niet langer nodig heeft, moet u deze intrekken. Voeg deze _clearObjectURL() -methode toe aan controller.js om dat af te handelen:

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

Dien een XHR-verzoek in

Voeg een _requestRemoteImageAndAppend() methode toe om een ​​XMLHttpRequest uit te voeren op een bepaalde afbeeldings-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();
};

Bij het laden van XHR creëert deze methode een ObjectURL uit het XHR-antwoord en voegt een <img> -element met deze ObjectURL toe aan de DOM.

Parseer voor afbeeldings-URL's in takenitems

Voeg nu een _parseForImageURLs() methode toe die alle nog niet verwerkte links vindt en deze controleert op afbeeldingen. Voor elke URL die op een afbeelding lijkt, voert u _requestRemoteImageAndAppend() uit:

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

Geef miniaturen weer in de takenlijst

Roep nu _parseForImageURLs() aan vanuit showAll() , showActive() en 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));
};

Doe hetzelfde voor 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) {
  ...
}

Beperk de weergegeven afbeeldingsafmetingen

Voeg ten slotte in _bower componenten/todomvc-common/base.css een CSS-regel toe om de grootte van de afbeelding te beperken:

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

Start uw voltooide Todo-app

Je bent klaar Stap 5! Laad uw app opnieuw en voeg een taakitem met een URL toe aan een afbeelding die online wordt gehost. Enkele URL's die u kunt gebruiken: http://goo.gl/nqHMF#.jpg of http://goo.gl/HPBGR#.png .

Voor meer informatie

Voor meer gedetailleerde informatie over enkele van de API's die in deze stap zijn geïntroduceerd, raadpleegt u:

Klaar om door te gaan naar de volgende stap? Ga naar Stap 6 - Taken exporteren naar het bestandssysteem »