Krok 5. Dodaj obrazy z internetu

W tym kroku poznasz:

  • Wczytywanie zasobów spoza aplikacji i dodawanie ich do DOM za pomocą XHR i ObjectURLs.

Szacowany czas potrzebny na ukończenie tego kroku: 20 minut.
Aby zobaczyć podgląd czynności, które wykonasz w tym kroku, przeskocz na dół strony ↓.

Jak CSP wpływa na wykorzystanie zasobów zewnętrznych

Platforma Aplikacje Chrome wymusza pełną zgodność aplikacji z zasadami CSP. Nie możesz bezpośrednio wczytywać zasobów DOM, takich jak obrazy, czcionki i CSS, spoza aplikacji Chrome pakietu SDK.

Jeśli chcesz wyświetlić obraz zewnętrzny w aplikacji, musisz zażądać go za pomocą XMLHttpRequest, przekształc go w obiekt Blob i utwórz ObjectURL. Ten ObjectURL można dodać do DOM, ponieważ odnosi się do elementu w pamięci w kontekście aplikacji.

Pokaż miniatury zadań do wykonania

Zmieńmy aplikację tak, aby szukała adresów URL obrazu w elemencie listy zadań. Jeśli adres URL wygląda jak obraz (na przykład np. kończy się na .png, .jpg, .svg lub .gif), zastosuj proces opisany powyżej, aby pokazać miniaturę obrazu obok adresu URL.

Aktualizuj uprawnienia

W aplikacji Chrome możesz wywoływać XMLHttpRequest do dowolnego adresu URL, o ile tylko podasz jego domenę w pliku manifestu. Ponieważ nie wiesz wcześniej, jaki adres URL obrazu wpisze użytkownik, poproś o pozwolenie wysyłać żądania do usługi "<all_urls>".

W pliku manifest.json poproś o parametr „” uprawnienia:

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

Tworzenie i czyszczenie adresów URL obiektów

W pliku controller.js dodaj metodę _createObjectURL(), aby tworzyć adresy URL obiektów z obiektu blob:

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

Adresy URL obiektów przechowują pamięć, więc jeśli nie potrzebujesz już obiektu ObjectURL, musisz go unieważnić. Dodaj to _clearObjectURL() do controller.js, aby to obsłużyć:

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

Wyślij żądanie XHR

Dodaj metodę _requestRemoteImageAndAppend(), aby wykonać żądanie XMLHttpRequest dla podanego adresu URL obrazu:

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

Podczas ładowania XHR ta metoda tworzy ObjectURL z odpowiedzi XHR i dodaje element <img>. z tym identyfikatorem ObjectURL do DOM.

Analizuj adresy URL obrazów w elementach listy zadań

Teraz dodaj metodę _parseForImageURLs(), która wykrywa wszystkie jeszcze nieprzetworzone linki i sprawdza je pod kątem obrazów. W przypadku każdego adresu URL, który wygląda jak obraz, uruchom polecenie _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]);
    }
  }
};

Renderuj miniatury na liście zadań do wykonania

Teraz zadzwoń do użytkownika _parseForImageURLs() z aplikacji showAll(), showActive() i 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));
};

Zrób to samo dla 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) {
  ...
}

Ograniczanie wymiarów wyświetlanych obrazów

Na koniec w pliku _bowercomponents/todomvc-common/base.css dodaj regułę CSS, by ograniczyć rozmiar pliku obraz:

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

Uruchom gotową aplikację Todo

Krok 5 ukończony. Załaduj ponownie aplikację i dodaj zadanie do wykonania z adresem URL do obrazu hostowanego online. Niektóre Możesz użyć adresów URL: http://goo.gl/nqHMF#.jpg lub http://goo.gl/HPBGR#.png.

Więcej informacji

Szczegółowe informacje o niektórych interfejsach API wprowadzonych w tym kroku znajdziesz tutaj:

Chcesz przejść dalej? Przejdź do sekcji Krok 6. Eksportuj zadania do systemu plików »