2022年1月26日 星期三

JavaScript : Blob URL

2022年1月26日 星期三

 因為想幫 HTML5 FUN 中的工具寫個所視即所得的題庫編輯器,最近一直在研究「content editable」,簡單的說,就是在 HTML 的 tag,例如常用的「div」加一個屬性「contenteditable="true"」,它就能變成一個可以允許使用者更改內容:


<div contenteditable="true">


哈!要讓使用者填資料,以前都是用 input、textarea 等元件,它們的缺點是比較單調些,只能純填入文字。利用 div 就什麼都能放了,像我的題庫中可以是文字、圖片或聲音,後兩者在題庫編輯器中,如果能夠直接呈現預覽的樣子,使用者就不會被一堆又臭又長,更看不懂的字串給嚇壞了。

「content editable」玩了兩、三天,目前在我的 HTML5 樂透摸彩機中,已經有一點雛形,可以試試看:


不過,哈哈哈!新手上路,臭蟲陸陸續續出現是正常的事!

在電腦上操作比較沒問題,在 iOS 上的 Safari 倒是狀況不少。像 CSS 中如果「-webkit-user-select: text;」沒設好,點了有設定「contenteditable="true"」的元件,游標就是出不來,連進門都沒有,還哪來的後續改內容。這部份在 Firefox 中也是,Firefox 要設定的是「-moz-user-select」。

對 iOS 來說,「-webkit-user-select: text;」設在啟用「contenteditable="true"」的 div,而像我題庫會用到的文字和圖片,再針對 div 中的元件設定「-webkit-user-select: auto;」即可。

但是~但是~一波好幾折,目前在我用來開發 HTML5 FUN 的 LimeJS 中,因為它預設會改變(取消)網頁中最上層元件的 touchstart、touchmove 的預設動作,在行動載具中拖曳時,頁面才不會跟著捲動。難怪無法進入 div 中編輯內容的狀況,只有在 iOS 的 Safari 中會發生(在 Android 應該也會),在 Windows 的 Chrome 或 Firefox 都正常。這部份會干擾在「contenteditable="true"」後,編輯題庫時游標的控制,還要再來想想怎處理。

在解決前述問題的過程中,又發現了很多問題,其中一個是本篇要記錄的重點「Blob URL」。

「Blob URL」是什麼「碗糕」?要不是今天在 iOS 中測試我程式,應該也遇不到這問題。簡單地描述一下狀況。

當我把某網站的圖片直接複製並貼到有啟用「content editable」的編輯區中後,當然囉!它會呈現我貼上的點片。但是在分析拿到的內容時, <img> 的 src ,在 Windows 的 Chrome 和 Firefox 是原網站中的網址,而在 iOS 的 Safari 中,卻是類似這樣的字串:


blob:http://192.168.2.101/a290568f-6e7d-41e8-b35b-55d13b6d189e


上面的「http://192.168.2.101/」是我測試用的 web server,但是圖片明明由 Internet 的網站中複製來的呀!如果打那串網址,肯定是沒那圖的。找了半天,才在底下這則討論串中,知道了一點眉目:


更詳細的內容可以參考 W3C 網站 FileAPI 第八大項中的說明 :


Stack Overflow 討論串中有人提到可以在當下把 src 指的路徑,讓 Safari 把真正的資料抓出來。試了一下果然可以。底下是我用 fetch 抓檔 Blob URL 資料,轉為 Base64 編碼的程序:


var blobToDataURL = function(blobURL,  callback) {
fetch(blobURL)
.then(response => response.blob())
.then( blob => {
var reader = new FileReader();
reader.onload = function(){ 
var base64 = this.result;
//將 public.XXX 換成 image/XXX
base64 = base64.replace(/public\./, 'image/');
if(typeof(callback)=='function') {
callback(base64);
}
};
try {
reader.readAsDataURL(blob);
}catch(error) { alert(error); };
});
};


轉為 DataURL Base64 編碼的圖片,它的 MimeType 的部份變成 public.XXX ,因為我的應用都是圖片,所以將它置換為圖片該有的 image/XXX。

現在待解決的問題還有一個,因為要讀取檔案,和原來的程序來比,會有時間差,這一點要再來想想如何解決。

【後記】在 iOS 10.3.4 中,貼上去圖片 src 是「webkit-fake-url」,待解決。




沒有留言:

張貼留言

 
雄::gsyan © 2009. Design by Pocket