ขั้นตอนที่ 4: เปิดลิงก์ภายนอกด้วย WebView

ในขั้นตอนนี้ คุณจะได้เรียนรู้เกี่ยวกับสิ่งต่อไปนี้

  • วิธีแสดงเนื้อหาเว็บภายนอกภายในแอปด้วยวิธีที่ปลอดภัยและอยู่ในแซนด์บ็อกซ์

เวลาโดยประมาณในการทำขั้นตอนนี้ให้เสร็จสิ้นคือ 10 นาที
หากต้องการดูตัวอย่างขั้นตอนที่ต้องทำในขั้นตอนนี้ ให้เลื่อนลงไปที่ด้านล่างของหน้านี้ ↓

ดูข้อมูลเกี่ยวกับแท็ก WebView

แอปพลิเคชันบางอย่างต้องนำเสนอเนื้อหาเว็บภายนอกต่อผู้ใช้โดยตรงแต่เก็บไว้ในประสบการณ์การใช้งานแอปพลิเคชัน เช่น ผู้รวบรวมข้อมูลข่าวอาจต้องการฝังข่าวจากเว็บไซต์ภายนอกด้วยการจัดรูปแบบ รูปภาพ และลักษณะการทำงานทั้งหมดของเว็บไซต์ต้นฉบับ สำหรับการใช้งานเหล่านี้และอื่นๆ แอป Chrome มีแท็ก HTML ที่กำหนดเองชื่อ webview

แอป Todo ที่ใช้ WebView

ติดตั้งแท็ก WebView

อัปเดตแอป Todo เพื่อค้นหา URL ในข้อความรายการสิ่งที่ต้องทำและสร้างไฮเปอร์ลิงก์ เมื่อคลิกลิงก์ จะเปิดหน้าต่างแอป Chrome ใหม่ (ไม่ใช่แท็บเบราว์เซอร์) ที่มี WebView แสดงเนื้อหา

อัปเดตสิทธิ์

ใน manifest.json ให้ขอสิทธิ์ webview:

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

สร้างหน้าเครื่องมือฝัง WebView

สร้างไฟล์ใหม่ในรูทของโฟลเดอร์โปรเจ็กต์และตั้งชื่อว่า webview.html ไฟล์นี้เป็นหน้าเว็บพื้นฐานที่มีแท็ก <webview> 1 แท็ก ดังนี้

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

แยกวิเคราะห์ URL ในรายการสิ่งที่ต้องทำ

ในตอนท้ายของ controller.js ให้เพิ่มเมธอดใหม่ที่ชื่อว่า _parseForURLs() ดังนี้

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

เมื่อใดก็ตามที่พบสตริงที่ขึ้นต้นด้วย "http://" หรือ "https://" ระบบจะสร้างแท็ก Anchor ของ HTML เพื่อล้อมรอบ URL

ค้นหา showAll() ใน controller.js อัปเดต showAll() เพื่อแยกวิเคราะห์ลิงก์โดยใช้เมธอด _parseForURLs() ที่เพิ่มไว้ก่อนหน้านี้ ดังนี้

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

ให้ทำแบบเดียวกันนี้สำหรับ showActive() และ 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));
};

และสุดท้าย เพิ่ม _parseForURLs() ไปยัง editItem():

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

ยังอยู่ระหว่าง editItem() ให้แก้ไขโค้ดเพื่อให้ใช้ innerText ของป้ายกำกับแทน innerHTML ของป้ายกำกับ ดังนี้

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;
  ...
}

เปิดหน้าต่างใหม่ที่มี WebView

เพิ่มเมธอด _doShowUrl() ลงใน controller.js วิธีนี้จะเปิดหน้าต่างแอป Chrome ใหม่ผ่าน chrome.app.window.create() โดยมี webview.html เป็นแหล่งที่มาของหน้าต่าง

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

ในโค้ดเรียกกลับ chrome.app.window.create() ให้สังเกตวิธีตั้งค่า URL ของ WebView ผ่านแอตทริบิวต์แท็ก src

สุดท้าย ให้เพิ่ม Listener เหตุการณ์การคลิกภายในตัวสร้าง Controller เพื่อเรียก doShowUrl() เมื่อผู้ใช้คลิกลิงก์

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

เปิดแอป Todo ที่เสร็จแล้ว

คุณทำขั้นตอนที่ 4 เสร็จแล้ว หากคุณโหลดแอปซ้ำและเพิ่มรายการสิ่งที่ต้องทำซึ่งมี URL แบบเต็มที่ขึ้นต้นด้วย http:// หรือ https:// คุณควรจะเห็นข้อความดังนี้

สำหรับข้อมูลเพิ่มเติม

สำหรับข้อมูลโดยละเอียดเพิ่มเติมเกี่ยวกับ API บางส่วนที่นำมาใช้ในขั้นตอนนี้ โปรดดูที่:

หากพร้อมที่จะไปยังขั้นตอนถัดไปแล้ว ไปที่ขั้นตอนที่ 5 - เพิ่มรูปภาพจากเว็บ »