在這個步驟中,您將瞭解:
- 如何從應用程式外部載入資源,並透過 XHR 和 ObjectURL 將資源新增至 DOM。
預計完成這個步驟的時間:20 分鐘。
如要預覽這個步驟中要完成的內容,請向下跳到本頁底部 ↓。
CSP 對外部資源使用的影響
Chrome 應用程式平台會強制您的應用程式完全符合內容安全政策 (CSP)。您無法直接從 Chrome 應用程式套件外部載入圖片、字型和 CSS 等 DOM 資源。
如要在應用程式中顯示外部圖片,您必須透過 XMLHttpRequest 要求圖片,然後將其轉換為 Blob,並建立 ObjectURL。這個 ObjectURL
可在應用程式環境中參照記憶體內項目,因此可以新增至 DOM。
顯示待辦事項縮圖
讓我們變更應用程式,尋找待辦事項中的圖片網址。如果網址的格式是圖片 (例如結尾為 .png、.jpg、.svg 或 .gif),請套用上述程序,在網址旁邊顯示圖片縮圖。
更新權限
在 Chrome 應用程式中,只要您在資訊清單中指定網域,就可以對任何網址進行 XMLHttpRequest 呼叫。由於您不會事先得知使用者會輸入的圖片網址,因此請向 "<all_urls>"
要求權限。
在 manifest.json 中取得「
"permissions": ["storage", "alarms", "notifications",
"webview", "<all_urls>"],
建立及清除 ObjectURL
在 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
,並將具有此 ObjectURL
的 <img>
元素新增至 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;
}
啟動已完成的待辦事項應用程式
您已完成步驟 5!重新載入應用程式,然後新增待辦事項項目,並附上線上代管圖片的網址。你可以使用下列網址:http://goo.gl/nqHMF#.jpg 或 http://goo.gl/HPBGR#.png。
瞭解詳情
如要進一步瞭解這個步驟介紹的某些 API,請參閱:
準備好繼續進行下一步了嗎?請參閱步驟 6 - 將待辦事項匯出至檔案系統 »