在這個步驟中,您將瞭解以下內容:
- 如何從應用程式外部載入資源,並透過 XHR 和 ObjectURLs 將資源加入 DOM。
完成這個步驟所需的時間:20 分鐘。
如要預覽您將在這個步驟中完成的內容,請向下捲動到本頁底部 ↓。
CSP 對外部資源的使用有何影響
Chrome 應用程式平台會強制您的應用程式完全遵循內容安全政策 (CSP)。 您無法在 Chrome 應用程式之外直接載入 DOM 資源,例如圖片、字型和 CSS 套件。
如果要在應用程式中顯示外部圖片,則必須透過 XMLHttpRequest 要求圖片。
轉換為 Blob,並建立 ObjectURL。這個ObjectURL
可以新增至
DOM 在應用程式情境中參照記憶體內的項目。
顯示待辦事項縮圖
接著請變更應用程式,以尋找待辦事項項目的圖片網址。如果網址看起來像圖片 ( 例如,以 .png、.jpg、.svg 或 .gif 結尾,套用上述程序來顯示 網址旁的縮圖。
更新權限
在 Chrome 應用程式中,您可以直接向任何網址發出 XMLHttpRequest 呼叫,但前提是您在
資訊清單。您無法事先得知使用者會輸入哪個圖片網址,因此可以向
向 "<all_urls>"
發出要求。
在 manifest.json 中要求「
"permissions": ["storage", "alarms", "notifications",
"webview", "<all_urls>"],
建立及清除物件網址
在 controller.js 中,新增 _createObjectURL()
方法,從 Blob 建立 ObjectURL:
Controller.prototype._createObjectURL = function(blob) {
var objURL = URL.createObjectURL(blob);
this.objectURLs = this.objectURLs || [];
this.objectURLs.push(objURL);
return objURL;
};
ObjectURL 會保留記憶體,因此不再需要 ObjectURL 時,請予以撤銷。新增此項目
使用 _clearObjectURL()
方法執行 controller.js,即可處理以下情況:
Controller.prototype._clearObjectURL = function() {
if (this.objectURLs) {
this.objectURLs.forEach(function(objURL) {
URL.revokeObjectURL(objURL);
});
this.objectURLs = null;
}
};
提出 XHR 要求
請新增 _requestRemoteImageAndAppend()
方法,以便對指定圖片網址執行 XMLHttpRequest:
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();
};
在 XHR 載入時,這個方法會根據 XHR 的回應建立 ObjectURL
,並新增 <img>
元素
運用這個 ObjectURL
傳送至 DOM
剖析待辦事項項目的圖片網址
接著新增 _parseForImageURLs()
方法,即可找出所有尚未處理的連結,並檢查這些連結是否
所以映像檔較小請對每個類似圖片的網址執行 _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]);
}
}
};
在待辦事項清單中顯示縮圖
現在從 showAll()
、showActive()
和 showCompleted()
呼叫 _parseForImageURLs()
:
/**
* 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));
};
對 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) {
...
}
限制顯示圖片的尺寸
最後,在 _bowercomponents/todomvc-common/base.css 加入 CSS 規則,藉此限制 圖片:
.thumbnail img[data-src] {
max-width: 100px;
max-height: 28px;
}
啟動已完成的 Todo 應用程式
您已完成步驟 5!請重新載入應用程式,並新增內含線上代管圖片網址的待辦事項項目。只有部分通知 可用的網址:http://goo.gl/nqHMF#.jpg 或 http://goo.gl/HPBGR#.png。
瞭解詳情
如要進一步瞭解這個步驟中導入的部分 API,請參閱:
準備好進行下一個步驟了嗎?前往步驟 6:將待辦事項匯出至檔案系統 »