前言 上傳圖片是常見的需求,多使用input標簽。本文主要介紹 input標簽的樣式美化 和 實現圖片預覽。 用到的知識點有: 1、input標簽的使用 2、filelist對象 和 file對象 3、fileReader對象 樣式美化 原生的input標簽樣式單一,且在不同瀏覽器下的表現還不一致。 ...
前言
上傳圖片是常見的需求,多使用input標簽。本文主要介紹 input標簽的樣式美化 和 實現圖片預覽。
用到的知識點有:
1、input標簽的使用
2、filelist對象 和 file對象
3、fileReader對象
樣式美化
原生的input標簽樣式單一,且在不同瀏覽器下的表現還不一致。所以為了美觀和統一,我們需要自定義input標簽的樣式。
實現的方式有很多中,這裡採用的是:用一個div將input標簽包裹,然後再將input標簽透明度設置為0,再對div設置自己需要的樣式。html和css如下:
<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; }View Code
這樣點擊div,其實也就點擊到了input標簽,可已正常觸發選擇文件的。
效果如下:
但是這樣就會產生一個問題,如何獲取選擇文件的文件名稱呢?需要用到file對象的name屬性
filelist和file對象--獲取文件名
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 對象 --實現圖片預覽
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,不嚴謹的地方和醜陋的樣式就多多包涵了。
再下一步就是要上傳圖片到伺服器了,會在下個隨筆中記錄。