原生JS上傳圖片(FormData,可預覽,一次多圖)

前言:

適合人羣:剛起步的前端新人。(先後端未分離的項目)全棧後端老大哥的前端需求(點名批評下jsp)。前端

解決問題:ios

1.普通js上傳一張圖片

2.普通js上傳一張圖片,提早預覽。而後再決定是否上傳。

3.普通js一次上傳多張圖片。
複製代碼

知識點:git

* FormData對象的使用(上傳圖片)
* FileReader對象的使用(轉換成base64可被預覽)
複製代碼

1.普通js上傳一張圖片

HTML代碼:github

須要一個input:file圖片上傳控件ajax

<input type="file" class="file" name="file" />
複製代碼

JS代碼:canvas

1.綁定change事件,這樣上傳點擊上傳的圖片就能夠獲取到axios

2.注意你可能會拿到這個 後端

別慌。由於對象的特殊,file對象是不會被開發人員所直接捕獲(可見)的。但確實存在。

這個對象有一個files屬性,返回的就是FileList對象。FileList對象看起來和數組同樣,但不是數組,不能使用forEach,可是有length屬性數組

能夠經過FileList.item(0) 或 FileList[0] 獲取對應的第1個file對象

3.將單個圖片對象放到FormData中。使用FormData的append方法。bash

注意: 對於加入圖片對象時: append()方法強烈建議使用三個參數的方法(2個參數的傳遞圖片時,可能出現問題)。分別是 (鍵名,圖片對象,圖片名稱)

普通的鍵值對可使用append(key,value)便可

4.完成了,就是這麼簡單。使用你熟悉的jq/axios/本身封裝的ajax發到後臺吧。

document.querySelector('.file').addEventListener('change', function(e) {
          //1.能夠經過this拿到這個file的DOM元素
          console.log(this)
          //1.  e 函數事件參數對象中也有這個file的DOM元素對象。使用e.target也能夠直接拿到
          console.log(e.target)
          //對開發人員屏蔽,因此直接 必須調用這個文件的DOM對象的files屬性,返回一個數組
          let files = e.target.files
          console.log(files)
          // console.log(files.item(0))
          // console.log(files[0])
          // 判斷一手是否有文件
          if (!files.length) return
          // 上傳文件 建立FormData
          let formData = new FormData()
          // upFile就是後臺接收的key
          formData.append('upFile', files[0], files[0].name)
          // 將formdata發送到後臺便可
          // 我用的 axios.post('url', formData)
        })
複製代碼

2.普通js上傳一張圖片,提早預覽。而後再決定是否上傳

相比上面那個一鍵上傳的功能,不能預覽的功能你很不爽吧。不少時候就是要先預覽下本地的圖片,可是還不能上傳到圖片服務器佔內存....

HTML代碼:

多了一個圖片標籤

<input type="file" class="file" name="file" />
<img src="" alt="" />
複製代碼

JS代碼: 直接提供一個將file對象轉base64方法。你只須要在獲取file對象後,先不着急封裝到FormData中,先轉base64看看效果,再作接下來操做

/*
         * 將file對象轉化爲base64編碼
         * file  目標file對象
         */
        function previewFile(file) {
          let reader
          if (file) {
            // 建立流對象
            reader = new FileReader()
            reader.readAsDataURL(file)
          }
          // 捕獲 轉換完畢
          reader.onload = function(e) {
            // 轉換後的base64就在e.target.result裏面,直接放到img標籤的src屬性便可
            document.querySelector('img').src = e.target.result
          }
        }
複製代碼

3.普通js一次上傳多張圖片。

大概是這個樣子,用戶能夠按住Ctrl或Shift能夠一次選擇多張。

1.HTML的input:file控件中多一個multiple屬性

HTML代碼:

<input type="file" class="file" name="file" multiple="multiple" />
複製代碼

JS代碼:

這裏須要注意下的是FormData的append方法。相同的key,是會自動追加的,並不會覆蓋,但注意須要使用getAll()才能完整獲取查看,get()和querySelector只獲取第一個相似

獲取到的formData中file數組是這個效果

document.querySelector('.file').addEventListener('change', function(e) {
          let files = e.target.files
          if (!files.length) return
          // 上傳文件 建立FormData
          let formData = new FormData()
          // 遍歷FileList對象,拿到多個圖片對象
          for (let i = 0; i < files.length; i++) {
            // formData中的append方法 若是已有相同的鍵,則會追加成爲一個數組  注意:這裏須要使用formData.getAll()獲取
            formData.append('upFile', files[i], files[i].name)
          }
          console.log(formData.getAll('upFile'))
          // 將formdata發送到後臺便可
          // 我用的 axios.post('url', formData)
        })
複製代碼

總結:

1.整體來講就是一些API的使用,另外還須要注意一些細節,例如斷定該file對象是不是圖片,斷定圖片的類型、大小等。可在file對象的 屬性查看。

2.本文的傳輸方式統一採用ajax異步,如需採用原生表單同步發送,只須要在FORM屬性上加一個enctype="multipart/form-data" 便可

3.關於圖片相關的還有一個壓縮也是個重要問題(不少時候上傳都是由大小限制的)。這個暫時沒有總結...大致是canvas壓縮,你們能夠根據須要自行搜一把,github上也有不少封裝好的。

2019.6.13

若有錯誤,歡迎指正!

固然有興趣你們也能夠一塊兒交流,學習(羣裏有大佬,歡迎活躍的同窗)!

打個廣告,貼個二維碼!

相關文章
相關標籤/搜索