話說,還是有不少項目里提供讓用戶上傳東西的。小到一個 wordpress 博客,大到一個文件存儲網站。為了更好的用戶體驗。來學習兩個新知識吧。HTML5 文件訪問(File Access: FileReader)和拖放(Drag and Drop)。或許下個項目就能用上了。

一、起因

minus

今天看到 twitter 上有人在分享 Min.us 這個網站。說是只要把圖片進去,就可以分享。是的,它確實是這樣。體驗了一翻,無論從界面,還操作的方便性上說,這體驗還真是很贊的。

不過,我更在意的是,他用了什么樣的技術。想著今晚回來瞄下代碼。這下,汗的事來了。這頁面看起來不像前端寫的啊。亂七八糟的。真是看不下去了。不過,為了更好的用戶體驗,看吧。從頁面的 HTML5 標簽猜測到可能用到 HTML5 的某些 API,再查一下 JS 發現了這兩行:

function isValidBrowser() {   var browser = BrowserDetect.browser;   var version = BrowserDetect.version;   var OS = BrowserDetect.OS;   //alert(browser+','+version+','+OS);   return (     (browser == 'Chrome' && version >= 6) ||     (browser == 'Firefox' && version >= 3.6) || 	(browser == 'Safari' && version >= 5.0 && OS == 'Mac') ||     ("FileReader" in self && "ondrag" in document)   ); } 

二、DEMO

先來個預覽吧,你可以先玩玩,再接著往下面看:HTML5 文件拖放上傳

三、如何實現

好吧,確定是使用HTML5。我們來看一下這種技術是怎么實現的吧。嗯,再回看上面的代碼,還有我提了這么多次,其實,它就用到兩個技術:

  1. FileReader,HTML5 File API
  2. Drag and Drop,似乎IE從 5.5 就支持了,都不敢說她是 HTML5 了

這里有兩篇比較詳細的文章,看(等看完我講的,你再去看吧):

  1. Native HTML5 Drag and Drop
  2. Reading local files in JavaScript

現在 1:10 am 了,同學。明天還要上班。而具體講來,還是需要很多時間滴。我們就簡單一點。說些應該注意的吧。具體的實現,你看我 DEMO 的代碼吧,和上面的文章吧。

一、 瀏覽器檢測 & 支持

支持的瀏覽器并不多,我測試的是 Filefox 和 Chrome, winSafari 5.0.2 沒通過。IE8 以下就更不用說了,當然,Opera 也沒有支持。

if (window.FileReader) { 	// 做事的 } else { 	alert('你的瀏覽器不支持啊,同學') } 

從 Minus 的代碼中可以看出,支持的有:

  1. Chrome 6+
  2. Firefox 3.6+
  3. Mac Safari 5.0+

其他的,就是浮云了。不過,這已經足夠了,因為我們可以用 hack 來實現。我們這里,就講可以用的吧。不可以的,就用原來項目中使用的方法吧。

二、注意事項

  1. 瀏覽器默認行為

    默認情況下,你向 Firefox 拖進一張圖片,他可能會重定向于新頁面。或者拖過一個鏈接,可能會讓頁面重定向。我想,你一定不會讓你的用戶一邊上傳,一邊又打開一個本地文件頁面,然后讓他再跑回來上傳的頁面。那就,阻止瀏覽器默認行為是非常有必要的。

  2. 事件綁定

    你可能發現了,在 DEMO 當我們把東西拖進容器的時候,容器的邊框樣式變成虛線。因為我這里綁定了一個事件,當文件進入目標是,添加一個 dragenter 的 CLASSNAME。這里需要注意的事,減少事件的解法,你可以在事件 ondragenter 的時候,添加 CLASSNAME ,而 ondragleave 的時候,刪除 CLASSNAME。但綁定在 dragover 上,他就像 mouseover ,在拖動的過程中不斷解發,這對于瀏覽器的負擔就很大了。可能會導致一些亂七八糟的,類似于崩潰之類的事。

  3. dataTransfer 的格式

    你可能需要用 e.dataTransfer.setData 和 e.dataTransfer.getData 來決定是否上傳用戶拖放的文件。

  4. File API 的狀態和 result

    檢測狀態,以便下一步操作,而 result 則可以實現本地預覽的功能,讓用戶知道自己要上傳的東西是什么。

  5. File API 的讀取格式
    • FileReader.readAsBinaryString(fileBlob) -  result 屬性會包含一個文件的二進制的格式
    • FileReader.readAsText(fileBlob, opt_encoding) -  result屬性將會包含一個文件的文本格式,默認解碼參數是 “utf-8”。
    • FileReader.readAsDataURL(file) -  result 將會包含一個文件的 DataURL 格式(圖片通常用這種方式)

四、具體的應用

其實我還沒有見到國內用上這個技術的網站。剛才瞄了一下 QQ 微博。也沒有。對于這些新技術。于我們前端開來,其實挑戰并不是會不會使用,而是,如何去使用。

比如,在支付寶,下次需要改版用戶上傳身份證認證的時候,或許我會去推動這樣的改進。又比如,如果是我在做 QQ 微博,或者任何一個微博,我將會提供一個讓用戶拖讓一張圖片就能上傳的功能。

HTML5 能用到的地方太多了。就慢你沒想法。因為別人其實并不清楚,連最清楚的你,前端,都不去推動,還能有誰去推動呢?

好吧。在接下來的項目中,你,或許也可以試試。