上傳圖片是常見的需求,多使用input標籤。本文主要介紹 input標籤的樣式美化 和 實現圖片預覽。css
用到的知識點有:html
一、input標籤的使用node
二、filelist對象 和 file對象數組
三、fileReader對象瀏覽器
原生的input標籤樣式單一,且在不一樣瀏覽器下的表現還不一致。因此爲了美觀和統一,咱們須要自定義input標籤的樣式。服務器
實現的方式有不少中,這裏採用的是:用一個div將input標籤包裹,而後再將input標籤透明度設置爲0,再對div設置本身須要的樣式。html和css以下:app
<div class="upload-file"> <input type="file" class="input-file" multiple="true"> // mulitiple屬性控制是否容許上傳多個文件 <span class="tip">點擊上傳圖片</span> </div>
.upload-file{ position: relative; width: 100px; padding: 10px 15px; border: 1px solid rgb(119, 154, 80); border-radius: 5px; background-color: rgb(66, 215, 142); color: #333333; font-size: 14px; text-align: center; overflow: hidden; } .upload-file span{ //單行顯示 text-overflow: ellipsis; white-space: nowrap; overflow: hidden; } .upload-file:hover{ //簡單的hover效果 font-size: 15px; border-color: rgb(39, 226, 81); } .upload-file input[type='file']{ height: 100%; width: 100%; position: absolute; //設置爲絕對定位,不會影響到其餘元素 top: 0; right: 0; opacity: 0; //透明度爲0 filter: alpha(opacity=0); cursor: pointer; }
這樣點擊div,其實也就點擊到了input標籤,可已正常觸發選擇文件的。異步
效果以下:ide
可是這樣就會產生一個問題,如何獲取選擇文件的文件名稱呢?須要用到file對象的name屬性this
input元素選擇文件後會返回FileList對象,好比
//input元素 var fileInput = document.querySelector('.input-file'); //filelist對象 var filelist = fileInput.files
//file對象
var file = filelist.item(0)
或者 var file = filelist[0]
咱們知道,每一個input[type='file']都有一個files屬性,返回的就是filelist 就和nodelist相似,不是數組。filelist就是由多個file對象組成的,每一個file對象都是一個文件。
filelist對象有個length屬性,能夠獲取長度;還有item(index)方法,能夠獲取到file對象,固然能夠經過 filelist[index]來獲取。
file對象經常使用的屬性有:
lastModified : 返回當前 File 對象所引用文件最後修改時間, 自 1970年1月1日0:00 以來的毫秒數。
lastModifiedDate : 返回當前 File 對象所引用文件最後修改時間的 Date 對象。
name : 文件名。
size : 文件大小。
type :文件類型。
因此咱們能夠經過file對象的name屬性來獲取到文件名,在修改到span元素中
var fileInput = document.querySelector('.input-file'); var tip = document.querySelector('.tip'); fileInput.addEventListener('change',function(e){ //監聽change事件,選擇文件後觸發 if(this.files.length === 1){ //處理文件名 tip.textContent = this.files[0].name; }else { tip.textContent = '已選擇 ' + this.files.length + ' 個文件'; } })
效果以下:
如今已經自定義了input[type='file']的樣式,並且實現了原有的功能。那麼如何實現圖片預覽呢?
FileReader 對象容許Web應用程序異步讀取存儲在用戶計算機上的文件(或原始數據緩衝區)的內容。也就是說FIlereader對象能夠讀取到input選擇的文件。filereader對象在讀取file對象時,當讀取完成時,readystate屬性的值會變爲DONE,會觸發load事件。並且有多種讀取方式:
readAsBinaryString()讀取完成後,result屬性中包含原始數據的二進制數據,readAsDataURL()讀取完成後,result屬性中包含data:url格式的數據,readAsText()讀取完成後,result屬性中包含字符串格式的數據,readAsArrayBuffer()result屬性中將包含一個ArrayBuffer對象以表示所讀取文件的內容。
這裏上傳的時圖片,因此使用readAsDataURL()讀取。如今html中加入個預覽觸發按鈕,而預覽圖片存放的區域。
//簡單結構 <div class="preview"> <button type="button" name="button">預覽</button> </div> //樣式 .preview{ margin-top: 10px; width: 150px; } .preview img{ margin: 5px 0; width: 100%; }
實現預覽功能,註釋中已有詳細解釋,再也不重複。注意必定要等filereader讀取完成後,再進行賦值,否則圖片的src屬性會是空的
var preview = document.querySelector('.preview') var previewBtn = preview.children[0]; previewBtn.addEventListener('click',function(e){ var filelist = fileInput.files; if(filelist.length < 1){ alert("未選擇圖片,沒法預覽"); return false; } [].slice.call(filelist).forEach(function(value,index){ //遍歷file對象 var fileReader = new FileReader(); //建立一個filereader對象 var img = new Image(); //建立一個圖片對象 fileReader.readAsDataURL(value) //讀取所上傳對的文件 fileReader.onload = function(){ img.src = this.result; //讀取完成後,賦值給img對象 preview.appendChild(img) //添加到預覽區域 } }) })
效果以下:
總結來講,就是 input[type='file']的files屬性 --> filelist對象 --> file對象 --> filereader對象讀取file對象。經過它們的一些參數值實現咱們想要的功能。因爲只是簡單demo,不嚴謹的地方和醜陋的樣式就多多包涵了。
再下一步就是要上傳圖片到服務器了,會在下個隨筆中記錄。