Schritt 4: Externe Links mit einer WebView öffnen

In diesem Schritt lernen Sie:

  • Hier erfährst du, wie du externe Webinhalte sicher in einer Sandbox in deiner App anzeigen kannst.

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

Weitere Informationen zum WebView-Tag

Bei einigen Anwendungen müssen externe Webinhalte dem Nutzer direkt präsentiert werden, aber innerhalb der App bleiben. Beispielsweise kann ein Nachrichtenaggregator die Nachrichten von externen Websites mit allen Formatierungen, Bildern und Funktionen der ursprünglichen Website einbetten. Für diese und andere Anwendungsfälle haben Chrome-Apps ein benutzerdefiniertes HTML-Tag namens webview.

Die Todo-App mit WebView

WebView-Tag implementieren

Aktualisieren Sie die To-Do-App, um im Text der Aufgabe nach URLs zu suchen und einen Hyperlink zu erstellen. Wenn der Link angeklickt wird, wird ein neues Chrome App-Fenster (kein Browsertab) mit einer Webansicht des Inhalts geöffnet.

Berechtigungen aktualisieren

Fordern Sie in manifest.json die Berechtigung webview an:

"permissions": [
  "storage",
  "alarms",
  "notifications",
  "webview"
],

Seite zum Einbetten von WebViews erstellen

Erstellen Sie im Stammverzeichnis Ihres Projektordners eine neue Datei und nennen Sie sie webview.html. Diese Datei ist eine einfache Webseite mit einem <webview>-Tag:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
</head>
<body>
  <webview style="width: 100%; height: 100%;"></webview>
</body>
</html>

URLs in Aufgaben parsen

Fügen Sie am Ende von controller.js eine neue Methode mit dem Namen _parseForURLs() hinzu:

  Controller.prototype._getCurrentPage = function () {
    return document.location.hash.split('/')[1];
  };

  Controller.prototype._parseForURLs = function (text) {
    var re = /(https?:\/\/[^\s"<>,]+)/g;
    return text.replace(re, '<a href="$1" data-src="$1">$1</a>');
  };

  // Export to window
  window.app.Controller = Controller;
})(window);

Immer wenn ein String gefunden wird, der mit „http://“ oder „https://“ beginnt, wird ein HTML-Anchor-Tag erstellt, das die URL umschließt.

Suchen Sie showAll() in controller.js. Aktualisieren Sie showAll(), um mit der zuvor hinzugefügten Methode _parseForURLs() nach Links zu parsen:

/**
 * 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.view.show(data);
    this.$todoList.innerHTML = this._parseForURLs(this.view.show(data));
  }.bind(this));
};

Wiederholen Sie diese Schritte für showActive() und showCompleted():

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

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

Fügen Sie abschließend _parseForURLs() zu editItem() hinzu:

Controller.prototype.editItem = function (id, label) {
  ...
  var onSaveHandler = function () {
    ...
      // Instead of re-rendering the whole view just update
      // this piece of it
      label.innerHTML = value;
      label.innerHTML = this._parseForURLs(value);
    ...
  }.bind(this);
  ...
}

Korrigieren Sie den Code in editItem() so, dass der innerText des Labels anstelle des innerHTML des Labels verwendet wird:

Controller.prototype.editItem = function (id, label) {
  ...
  // Get the innerHTML of the label instead of requesting the data from the
  // Get the innerText of the label instead of requesting the data from the
  // ORM. If this were a real DB this would save a lot of time and would avoid
  // a spinner gif.
  input.value = label.innerHTML;
  input.value = label.innerText;
  ...
}

Neues Fenster mit WebView öffnen

Fügen Sie controller.js eine _doShowUrl()-Methode hinzu. Diese Methode öffnet über chrome.app.window.create() ein neues Chrome App-Fenster mit webview.html als Fensterquelle:

  Controller.prototype._parseForURLs = function (text) {
    var re = /(https?:\/\/[^\s"<>,]+)/g;
    return text.replace(re, '<a href="$1" data-src="$1">$1</a>');
  };

  Controller.prototype._doShowUrl = function(e) {
    // only applies to elements with data-src attributes
    if (!e.target.hasAttribute('data-src')) {
      return;
    }
    e.preventDefault();
    var url = e.target.getAttribute('data-src');
    chrome.app.window.create(
     'webview.html',
     {hidden: true},   // only show window when webview is configured
     function(appWin) {
       appWin.contentWindow.addEventListener('DOMContentLoaded',
         function(e) {
           // when window is loaded, set webview source
           var webview = appWin.contentWindow.
                document.querySelector('webview');
           webview.src = url;
           // now we can show it:
           appWin.show();
         }
       );
     });
  };

  // Export to window
  window.app.Controller = Controller;
})(window);

Im chrome.app.window.create()-Callback wird die URL der WebView über das Tag-Attribut src festgelegt.

Fügen Sie zuletzt einen Klickereignis-Listener innerhalb des Konstruktors Controller hinzu, um doShowUrl() aufzurufen, wenn ein Nutzer auf einen Link klickt:

function Controller(model, view) {
  ...
  this.router = new Router();
  this.router.init();

  this.$todoList.addEventListener('click', this._doShowUrl);

  window.addEventListener('load', function () {
    this._updateFilterState();
  }.bind(this));
  ...
}

Fertige Todo-App starten

Sie haben Schritt 4 abgeschlossen! Wenn Sie Ihre App aktualisieren und eine Aufgabe mit einer vollständigen URL hinzufügen, die mit http:// oder https:// beginnt, sollte Folgendes angezeigt werden:

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 5: Bilder aus dem Web hinzufügen »