HTML5 - 使用本地文件

本篇文章的主要目的是介紹本地文件相關(guān) API 的使用,好的蚕礼,廢話不多說(shuō)梢什,下面直接開(kāi)始。


基礎(chǔ)的 File API

File Api 提供了在瀏覽器中與本地文件進(jìn)行交互的最基礎(chǔ)的方法囤躁,不過(guò)值得注意的是荔睹,由于安全問(wèn)題,開(kāi)發(fā)者并不能主動(dòng)的去訪問(wèn)客戶端的文件信息严沥,也就是說(shuō)這一過(guò)程需要用戶的參與中姜,最常用的獲取本地文件的手段莫過(guò)于兩種:

  1. 用戶通過(guò) input[type = file] 控件選擇了本地某個(gè)文件丢胚。
  2. 用于通過(guò)拖拽將本地的某一文件拖到瀏覽器完成上傳。

通過(guò)上面兩種形式携龟,我們都可以獲取到可以操作的 File 接口峡蟋,不過(guò)還有一點(diǎn)值得注意的是华望,無(wú)論是通過(guò)利用控件的形式還是通過(guò)拖拽的形式仅乓,用戶都可以同時(shí)選中多個(gè)文件,而當(dāng)用戶選擇多個(gè)文件的時(shí)候我們獲取到的其實(shí)是 FileList 接口宾抓,顧名思義豫喧,它就是一個(gè) File 接口的集合。

那么讲衫,通過(guò) File 接口我們能夠獲取到哪些信息呢鸟妙?

  1. name: 文件名
  2. type: ASCII 編碼,MIME 格式的文件類型。
  3. size: 文件所占的字節(jié) ( byte )忽匈。
  4. lastModifiedDate: 文件最后修改的日期和時(shí)間丹允。

注: File API 不能遍歷文件目錄。

通過(guò)上面介紹的這些內(nèi)容折柠,我們就可以很輕易的寫(xiě)出一個(gè)小 demo批狐,就像下面的這樣。

demo01.png

其實(shí)現(xiàn)過(guò)程就是利用 input[type=file] 控件選擇多個(gè)文件承冰,不過(guò)在這里我們并沒(méi)有直接使用這個(gè)控件食零,而是利用 button 來(lái)觸發(fā)這個(gè)控件的功能。然后通過(guò)用戶選擇的文件會(huì)返回一個(gè) FileList 對(duì)象娜搂,通過(guò)對(duì)其包含的每個(gè) File 進(jìn)行屬性的讀取即可。其核心代碼如下:

uploadButton.addEventListener("click", function() {
    fileInput.click();
}, false);

fileInput.addEventListener("change", function() {
    if (fileInput.files) {
        var length = fileInput.files.length;
        for(var i = 0; i < length; i++) {
            fileList.appendChild(getFileDetailDIV(fileInput.files[i]));
        }
    }
}, false);

這個(gè)時(shí)候這個(gè)小 demo 還不夠人性化考廉,畢竟有的人他就是不喜歡利用控件上傳文件恳谎,他就是喜歡利用拖放將文件傳上來(lái)因痛,那么為了這部分用戶,我們就得多費(fèi)點(diǎn)腦筋了鸵膏,怎么才能利用拖放獲取到一個(gè)文件的信息呢谭企?

在這之前,我想插入一些拖放的知識(shí)非区。因?yàn)榫W(wǎng)頁(yè)中并不是每一種元素都可以成為放置目標(biāo)盹廷,所以如果想自定義放置目標(biāo),那么我們需要修改 dragoverdragenter 的默認(rèn)行為管怠,代碼如下:

var droptarget = document.getElementById("custom-target");

droptarget.addEventListener("dragenter", function(e) {
    e.preventDefault();
}, false);

droptarget.addEventListener("dragover", function(e) {
    e.preventDefault();
}, false);

還有一點(diǎn)值得注意的是缸榄,當(dāng)你將目標(biāo)拖拽到地點(diǎn)以后,鼠標(biāo)松開(kāi)的時(shí)候就會(huì)觸發(fā) drop 事件她肯,不過(guò)放置事件也是有默認(rèn)行為的欲低,比如當(dāng)拖拽的目標(biāo)是圖片的時(shí)候,頁(yè)面就會(huì)轉(zhuǎn)向圖片瑞筐,當(dāng)拖拽的目標(biāo)是音樂(lè)或者視屏的時(shí)候,頁(yè)面就會(huì)按照默認(rèn)的方式打開(kāi)這些文件块蚌,所以如果不想這些事情發(fā)生膘格,我們需要阻止 drop 事件的默認(rèn)行為。

最后一點(diǎn)纱控,當(dāng)我們拖拽文件的時(shí)候菜秦,通過(guò) dataTransfer,files 就可以獲得選中的文件,而且其返回的結(jié)果是 FileList 接口尔店。下面就讓我們以拖拽的形式完成上面的功能主慰。

demo02.png

其核心代碼如下所示:

dragtarget.addEventListener("dragenter", function(e) {
    e.preventDefault();
}, false);

dragtarget.addEventListener("dragover", function(e) {
    e.preventDefault();
}, false);

dragtarget.addEventListener("drop", function(e) {
    e.preventDefault();

    var files = e.dataTransfer.files,
        length = files.length;

    for(var i = 0; i < length; i++) {
        fileList.appendChild(getFileDetailDIV(files[i]));
    }
}, false);

File Reader

上面已經(jīng)介紹了 File API 的使用共螺,不過(guò)僅僅是能夠獲取到文件的屬性,實(shí)用價(jià)值非常有限沙庐,所以在 HTML5 File API 中提供了一個(gè)新的接口 FileReader佳吞,該接口為開(kāi)發(fā)者提供了從客戶端 JS 異步讀取文件的方法底扳,屬性和事件贡耽,下面就先來(lái)看看它提供的四種不同的讀取方法。

  1. readAsArrayBuffer( Blob ): 以 ArrayBuffer 格式返回文件內(nèi)容阱冶。
  2. readAsBinaryString( Blob ): 以二進(jìn)制字符串的形式返回文件內(nèi)容滥嘴。
  3. readAsText( Blob, [, encoding] ): 以 DOMString 文本返回文件內(nèi)容。
  4. readAsDataURL( Blob ): 以數(shù)據(jù) URL DOMString 返回文件內(nèi)容镊叁。

事件如下:

  1. loadstart: 文件讀取操作開(kāi)始時(shí)觸發(fā)。
  2. progress: 瀏覽器讀取文件過(guò)程中觸發(fā)疤苹。
  3. abort: 執(zhí)行放棄操作時(shí)觸發(fā)敛腌。
  4. error: 文件讀取過(guò)程中出現(xiàn)錯(cuò)誤時(shí)觸發(fā)。
  5. load: 文件成功讀取后觸發(fā)尤莺。
  6. loadend 文件讀取完成后(無(wú)論成功或者失斝坠琛)觸發(fā)。

既然已經(jīng)知道了這么多的事件和方法捷绑,那么我們就的知道當(dāng)讀取完成后氢妈,我們需要的信息存放在何處?

通過(guò)上面的介紹壮吩,我們已經(jīng)知道當(dāng)文件讀取成功后加缘,會(huì)觸發(fā) load 事件拣宏,我們想要的事件就在 load 事件中的 event.target.result 中。下面我們針對(duì)各個(gè)方法做實(shí)驗(yàn)宋下,首先創(chuàng)建一個(gè)文本 test.txt辑莫,其內(nèi)容如下:

You can import usage data from your Google Analytics account and see exactly how well a feature is supported among your own site's visitors. Look under the Settings panel to get started!

關(guān)于 readAsArrayBuffer()readAsBinaryString() 這兩個(gè)方法在此就不演示了,因?yàn)槲覀€(gè)人對(duì) ArrayBuffer 的應(yīng)用場(chǎng)景還不是很清楚枝笨,所以下面直接利用 readAsText()readAsDataURL() 這兩個(gè)方法。

利用 readAsText() 的代碼如下:

    var fileReader = new FileReader();
    fileReader.addEventListener("load", function(e) {
        console.log(e.target.result);
    }, false);
    fileReader.readAsDataURL(file);

其返回的結(jié)果如下所示:

demo03.png

可見(jiàn)昭躺,它只是將你選擇的文本讀取出來(lái)了领炫,其實(shí)通過(guò)方法的名字你可能也已經(jīng)猜出大概了张咳。這有什么用呢?很明顯葱峡,我們可以利用這個(gè)方法編寫(xiě)一個(gè)在線閱讀或者修改的小應(yīng)用龙助。

還有一個(gè)方法是 readAsDataURL(), 這個(gè)方法的返回值如下:

demo04.png

可見(jiàn)提鸟,這個(gè)方法只是返回一個(gè) URL 地址,而通過(guò)這個(gè)地址我們就可以獲取到選中的文件称勋,這個(gè)方法非常的有用赡鲜,比如你想開(kāi)發(fā)圖片預(yù)覽相關(guān)的功能或者是在線播放本地音頻的應(yīng)用,都可以利用該方法獲取到一個(gè)連接到本地資源的 URL嘲更,然后進(jìn)行操作揩瞪。在以前,要完成同樣的功能,必須要將相應(yīng)的圖片或者資源上傳到服務(wù)器才可以使用纹因。


好了瞭恰,先寫(xiě)到這里,如果日后用到與文件操作相關(guān)的屬性,還會(huì)更新本文章密任!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末浪讳,一起剝皮案震驚了整個(gè)濱河市涌萤,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌透揣,老刑警劉巖川抡,帶你破解...
    沈念sama閱讀 206,126評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件崖堤,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡放坏,警方通過(guò)查閱死者的電腦和手機(jī)老玛,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén)蜡豹,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人镜廉,你說(shuō)我怎么就攤上這事娇唯。” “怎么了塔插?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,445評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵想许,是天一觀的道長(zhǎng)断序。 經(jīng)常有香客問(wèn)我违诗,道長(zhǎng)疮蹦,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,185評(píng)論 1 278
  • 正文 為了忘掉前任亮蒋,我火速辦了婚禮妆毕,結(jié)果婚禮上笛粘,老公的妹妹穿的比我還像新娘。我一直安慰自己薪前,他們只是感情好示括,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,178評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著鳍侣,像睡著了一般吼拥。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上惑折,一...
    開(kāi)封第一講書(shū)人閱讀 48,970評(píng)論 1 284
  • 那天惨驶,我揣著相機(jī)與錄音敛助,去河邊找鬼。 笑死休建,一個(gè)胖子當(dāng)著我的面吹牛评疗,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播砌些,決...
    沈念sama閱讀 38,276評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼加匈,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼雕拼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起偎球,我...
    開(kāi)封第一講書(shū)人閱讀 36,927評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤辑甜,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后猫牡,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體邓线,經(jīng)...
    沈念sama閱讀 43,400評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡褂痰,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,883評(píng)論 2 323
  • 正文 我和宋清朗相戀三年缩歪,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片主籍。...
    茶點(diǎn)故事閱讀 37,997評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡逛球,死狀恐怖颤绕,靈堂內(nèi)的尸體忽然破棺而出祟身,到底是詐尸還是另有隱情物独,我是刑警寧澤,帶...
    沈念sama閱讀 33,646評(píng)論 4 322
  • 正文 年R本政府宣布婉陷,位于F島的核電站秽澳,受9級(jí)特大地震影響戏羽,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜蛛壳,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,213評(píng)論 3 307
  • 文/蒙蒙 一衙荐、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧砌函,春花似錦溜族、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,204評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)况既。三九已至,卻和暖如春棒仍,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背癞尚。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,423評(píng)論 1 260
  • 我被黑心中介騙來(lái)泰國(guó)打工浇揩, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,423評(píng)論 2 352
  • 正文 我出身青樓膜廊,卻偏偏與公主長(zhǎng)得像淫茵,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子铆铆,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,722評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,499評(píng)論 25 707
  • 《裕語(yǔ)言》速成開(kāi)發(fā)手冊(cè)3.0 官方用戶交流:iApp開(kāi)發(fā)交流(1) 239547050iApp開(kāi)發(fā)交流(2) 10...
    葉染柒丶閱讀 25,993評(píng)論 5 19
  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)碍论,斷路器谅猾,智...
    卡卡羅2017閱讀 134,599評(píng)論 18 139
  • 一個(gè)優(yōu)秀的人,無(wú)論走到哪里都會(huì)受人尊重鳍悠,而一個(gè)快樂(lè)的人税娜,走到哪里都會(huì)被人圍繞。 這個(gè)人不一定優(yōu)秀藏研,可他足夠...
    日復(fù)一日的夢(mèng)想閱讀 350評(píng)論 0 0
  • 那是最美好的時(shí)代敬矩,那是最糟糕的時(shí)代;那是智慧的年頭蠢挡,那是愚昧的年頭弧岳;那是信仰的時(shí)期,那是懷疑的時(shí)期袒哥;那是光明的季節(jié)...
    三宅一生er閱讀 238評(píng)論 0 0