摘要:在日常項目開發中,圖片上傳是一個十分常見的場景。在圖片拖拽上傳這個業務場景中,被拖拽元素為頁面外部的圖片文件,故此處僅用到目標元素的各個事件。具體實現代碼如下至此,圖片上傳的常用知識點以梳理完畢,歡迎補充。
在日常項目開發中,圖片上傳是一個十分常見的場景。而現在的各種UI框架都提供了自己的上傳組件,網上第三方的上傳組件也多如牛毛。可能你早已習慣了直接使用這些現成的組件,然而對于其具體的實現,卻并未深入解析。本文將通過簡單的代碼,為你解析圖片上傳的各個知識點。
樣式自定義既然是上傳,肯定需要使用到標簽了。然而,默認的input到標簽樣式不僅單一,且在各個瀏覽器下的表現也不相同,所以通常需要對input進行樣式自定義。但標簽對于樣式的修改并不十分友好。解決方法很多,最常用的是將標簽隱藏,然后通過一個標簽進行關聯,然后直接修改標簽的樣式來實現。代碼如下:
圖片校驗
在上傳之前,一般會對文件進行各種校驗,例如文件類型,大小,格式,尺寸等。
其中文件類型,可通過設置標簽的accept來指定文件類型。但accept屬性并不能完全禁止用戶上傳指定類型之外的文件。故可以通過上傳文件的各個屬性進行校驗攔截。校驗前,我們需要通過change事件的事件對象來獲取到上傳的文件:
event.target.files
可以獲取到上傳文件列表。列表中對象包含如下信息:
{ lastModified: 1524153515000 lastModifiedDate: Thu Apr 19 2018 23:58:35 GMT+0800 (中國標準時間) {} name: "589adfbfe821c.jpg" size: 1357444 type: "image/jpeg" webkitRelativePath: "" }
從該對象中,我們可以獲取到文件大小,文件類型,文件名等信息,從而可以在上傳之前對這些信息進行校驗,從而攔截掉不合法的文件。
然而,從file對象中,我們并不能獲取圖片的尺寸信息。而在我們的業務中,很多場景都需要限制上傳圖片的尺寸為某一個固定值,或者是某一個比例。以減少后期顯示時的適配問題。要實現對上傳圖片尺寸對校驗,我們需要使用到FileReader和Image。
FileReader對象允許Web應用程序異步讀取存儲在用戶計算機上的文件。
Image()函數將會創建一個新的HTMLImageElement實例。它的功能等價于document.createElement("img")。
這里,我們需要用到fileReader的readAsDataURL()方法來讀取上傳文件信息,通過onload處理事件來獲取讀取到的文件信息。如下:
const reader = new FileReader(); reader.readAsDataURL(file); reader.onload = e => { console.log(e.target.result) }
代碼中,file為我們之前獲取到的文件列表files中的文件對象。e.target.result為讀取到到文件內容。
之后通過new Image()函數創建一個新的HTMLImageElement實例,并將該實例的src賦值為fileReader讀取到到文件內容。即可得到一個該文件的HTMLImageElement實例,通過該實例,我們便可以讀取到該圖片的尺寸信息。具體代碼如下:
const image = new Image(); image.src = e.target.result; image.onload = () => { console.log(image.width, image.height); }圖片上傳預覽
在之前的開發中,圖片上傳顯示通常會采用先將文件上傳,預覽圖片直接展示上傳到服務器中到圖片來實現,但這樣無法達到上傳前預覽該圖片的目的,且會造成許多垃圾圖片的上傳。
通過前面對于獲取圖片尺寸研究。相信你能很快想到一種更加優雅的圖片預覽方案,既然我們已經獲取到了該文件的HTMLImageElement實例,那么我們直接將該實例append到頁面的容器Dom中不久行了。或者直接將獲取到的文件設置到已存在的image標簽的src屬性中。圖片上傳預覽就是這么簡單。
圖片上傳與上傳進度展示圖片的上傳,我們可以直接通過form標簽搭配表單的submit()方法來實現圖片的上傳。然而,這樣我們就無法在上傳前進行上傳文件的校驗與攔截。同時需要用戶主動觸發提交操作。要想讓我們之前做的上傳前的攔截工作不白做,我們需要去在合適的時候,主動觸發文件的上傳操作。
這里,需要使用到FormData對象,來將入參對象數據轉為表單數據。
FormData對象用以將數據編譯成鍵值對,以便用XMLHttpRequest來發送數據。其主要用于發送表單數據,但亦可用于發送帶鍵數據(keyed data),而獨立于表單使用。如果表單enctype屬性設為multipart/form-data ,則會使用表單的submit()方法來發送數據,從而,發送數據具有同樣形式。
首先我們創建一個formData對象,然后通過append() 方法來添加字段。如下:
const formData = new FormData(); formData.append("file", file);
注意,formData雖然為一個對象,但通過console.log卻無法打印出其具體的值,只會得到FormData {}。
接下來創建一個XMLHttpRequest對象,用來發送ajax請求。并且通過該XMLHttpRequest對象的upload.onprogress方法,可以實時獲取到上傳信息,并進一步獲取到上傳的進度。具體代碼如下:
const client = new XMLHttpRequest() client.open("POST", uploadUrl) client.upload.onprogress = function(e) { if (e.lengthComputable) { let total = e.total; let loaded = e.loaded; let percentage = parseFloat(loaded / total).toFixed(2); } } client.send(formData)
上面代碼中,uploadUrl為上傳的URL。通過upload.onprogress的事件對象,可以獲取到當前進度已上傳的文件大小以及完整文件大小,通過這兩個大小參數,可以很容易計算出已上傳文件的比例,之后是顯示上傳進度條、還是展示進度數據,就可以隨意操作了。
拖拽上傳除了傳統的點擊選擇上傳文件外,拖拽文件上傳也是一個十分常見的場景。要使用拖拽上傳,就需要使用H5的拖放方法drop 和 drag方法。除了這兩個主要的方法外,還有拖放的不同階段觸發的多個方法,常用的拖拽方法如下:
ondragstart 事件:當拖拽元素開始被拖拽的時候觸發的事件(作用對象為被拖曳元素)
ondrag:在元素拖動期間不停的觸發該事件,與touchmove事件類似。(作用對象為被拖曳元素)
ondragend 事件:當拖拽完成后觸發的事件(作用對象為被拖曳元素)
ondragenter 事件:當拖曳元素進入目標元素的時候觸發的事件(作用對象為目標元素)
ondragover 事件:拖拽元素在目標元素上移動的時候觸發的事件(作用對象為目標元素)
ondragleave 事件:拖拽元素在目標元素上移動的時候觸發的事件(作用對象為目標元素)
ondrop 事件:被拖拽的元素在目標元素上同時鼠標放開觸發的事件(作用對象為目標元素)
拖拽的各個事件類似與touch事件的各個階段。然而需要注意的是,拖拽的各個事件,有著自己的作用對象,作用對象分為‘被拖拽元素’和‘目標元素’。被拖拽元素 為拖拽的那個Dom元素,主要使用在頁面內Dom拖拽移動的場景。目標元素為接收被拖拽元素的元素區域。當被拖拽元素進入到該區域,便會觸發目標對象的一系列事件。
在圖片拖拽上傳這個業務場景中,被拖拽元素為頁面外部的圖片文件,故此處僅用到目標元素的各個事件。我們可以通過這些事件來修改目標區域樣式等。核心的兩個事件為ondragover和ondrop事件。可能你覺得我只需要在松開鼠標時獲取拖拽的文件就行,因此只需要使用ondrop事件就行了?但是,由于瀏覽器的默認行為,ondrop事件并不會被觸發。因此,需要使用e.preventDefault(); 來阻止掉 ondropover的瀏覽器默認事件,從而保證ondrop事件的觸發。通過ondrop事件的事件對象,我們可以獲取到跟event.target.files相同的文件列表,獲取方法為event.dataTransfer.files;然而,當你這么寫完之后,進行拖拽之后,你會發現瀏覽器自動跳轉到了該圖片的預覽頁。這也是由于瀏覽器的默認行為導致,因此也需要使用e.preventDefault();來阻止掉瀏覽器的默認行為。這樣,便可以進行后續的文件校驗操作來。
具體實現代碼如下:
至此,圖片上傳的常用知識點以梳理完畢,歡迎補充。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/99032.html
摘要:責編現代化的方式開發一個圖片上傳工具前端掘金對于圖片上傳,大家一定不陌生。之深入事件機制前端掘金事件綁定的方式原生的事件綁定方式有幾種想必有很多朋友說種目前,在本人目前的研究中,只有兩種半兩種半還有半種的且聽我道來。 Ajax 與數據傳輸 - 前端 - 掘金背景 在沒有ajax之前,前端與后臺傳數據都是靠表單傳輸,使用表單的方法傳輸數據有一個比較大的問題就是每次提交數據都會刷新頁面,用...
摘要:馬爾代夫之行重頭戲這一年的工作情況這一年,個人感覺還是做了不少事情,主要集中在我們公司的前端領域,同時也給整個技術團隊不少的建議,引入了不少新的東西和方式,總結起來比較重要的在下面五個方面。 如果想看技術相關的,下拉到后面的重頭戲就是了。 一個活動頁面 在15年末的時候,加入到羅輯思維,剛過來就接手了一個微信朋友圈要傳播的活動頁面,效果頁面大概和當時錘子手機的活動頁面漂亮的不像實力派類...
閱讀 1961·2021-11-23 09:51
閱讀 873·2021-11-19 09:40
閱讀 829·2021-10-27 14:20
閱讀 5004·2021-10-09 09:52
閱讀 3297·2021-10-09 09:44
閱讀 1729·2021-10-08 10:05
閱讀 5053·2021-09-09 11:47
閱讀 3481·2019-08-30 12:47