整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          實現HTML5網站中常見的拖拽上傳文件

          我們學習了 HTML 提供的原生拖放(drag & drop)后,是時候想一想這個東西可以用來作什么可以在什么時候使用使用的場景等等

          場景分析

          當我們在注冊成功一個賬戶時,一般網站會讓我們上傳我們的用戶頭像,或者在實名認證的時候會涉及到身份證圖片上傳到等,這時候我們可以使用input提供的file屬性進行選擇本地文件進行上傳。

          我們再想一下,當在電腦端的情況下,當用戶打開文件選擇框時再尋找圖片對應的文件夾,再進行選取文件的時候是不是會有點麻煩呢?我們可不可以讓用戶找到圖片文件,直接引入實現上傳呢?答案是可以的。

          怎么做

          經過這些分析后,我們可以嘗試使用 HTML5 提供的拖拽,使得目標元素增加讀取文件功能,然后使用 ajax 實現圖片上傳。

          談一談我們需要使用到的技術:

          • Drag & Drop: HTML5 基于拖拽的事件機制
          • File API: 可以很方便的讓 Web 應用訪問文件對象,File API 包括 FileList、Blob、File、FileReader、URI scheme,本文主要講解拖拽上傳中用到的 FileList 和 FileReader 接口。
          • FormData: FormData 是基于 XMLHttpRequest Level 2 的新接口,可以方便 web 應用模擬 Form 表單數據,最重要的是它支持文件的二進制流數據,這樣我們就能夠通過它來實現 AJAX 向后端發送文件數據了。

          HTML5 拖拽事件

          關于 Drag & Drop 拖拽事件,之前我寫過一篇專門介紹的文章,HTML5-拖拽,大家有興趣的話可以點擊鏈接查看,我在這里就不在多啰嗦了~下面直接出拖拽上傳的簡要代碼示例

          var oDragWrap = document.body;
          //拖進
          oDragWrap.addEventListener(
           "dragenter",
           function(e) {
           e.preventDefault();
           },
           false
          );
          //拖離
          oDragWrap.addEventListener(
           "dragleave",
           function(e) {
           dragleaveHandler(e);
           },
           false
          );
          //拖來拖去 , 一定要注意dragover事件一定要清除默認事件
          //不然會無法觸發后面的drop事件
          oDragWrap.addEventListener(
           "dragover",
           function(e) {
           e.preventDefault();
           },
           false
          );
          //扔
          oDragWrap.addEventListener(
           "drop",
           function(e) {
           dropHandler(e);
           },
           false
          );
          var dropHandler = function(e) {
           //將本地圖片拖拽到頁面中后要進行的處理都在這
          };
          

          獲取文件數據 HTML5 File API

          File API 中的 FileReader 接口,作為 File API 的一部分,FileReader 專門用來讀取文件。我們在這里主要介紹一些 File API 中的 FileList 接口,它主要通過兩個途徑獲取本地文件列表,一是<input type="file"/>的表單形式,另一種則是e.dataTransfer.files拖拽事件傳遞的文件信息。

          var fileList = e.dataTransfer.files;
          

          使用 files 方法將會獲取到拖拽文件的數組形式的數據,每個文件占用一個數組的索引,如果索引不存在文件數據,將返回 Null。可以通過length屬性獲取文件的數量。

          var fileNum = fileList.length;
          

          拖拽上傳需要注意的是需要判斷兩個條件

          1. 拖拽的是文件而不是頁面的元素
          2. 拖拽的是圖片而不是其他類型的文件,可以通過 file.type 屬性獲取文件的類型
          // 檢測是否是拖拽文件到頁面的操作
          if (fileList.length === 0) {
           return;
          }
          // 檢測文件是不是圖片
          if (fileList[0].type.indexOf("image") === -1) {
           return;
          }
          

          下面我們看看結合之前的拖拽事件,來實現拖拽圖片并在頁面中預覽

          var dropHandler = function(e) {
           e.preventDefault(); //獲取文件列表
           var fileList = e.dataTransfer.files;
           //檢測是否是拖拽文件到頁面的操作
           if (fileList.length == 0) {
           return;
           }
           //檢測文件是不是圖片
           if (fileList[0].type.indexOf("image") === -1) {
           return;
           }
           //實例化file reader對象
           var reader = new FileReader();
           var img = document.createElement("img");
           reader.onload = function(e) {
           img.src = this.result;
           oDragWrap.appendChild(img);
           };
           reader.readAsDataURL(fileList[0]);
          };
          

          當完成以上操作后,相信你可以成功的完成了拖拽圖片預覽的操作。當你查看 img 標簽時會發現,img的src屬性是一個超長的文件二進制數據,當你需要很多這種的img元素時,建議將展示區域脫離文檔流,讓其絕對定位減少頁面的 reflow

          AJAX 上傳圖片

          既然已經獲取到拖拽到web頁面中的圖片數據了,下一步就是將其發送到服務器端。

          總結

          1. 監聽拖拽: 監聽頁面元素的拖拽事件,包括: dragenter、dragover、dragleave 和drop,一定要將dragover的默認事件取消掉,不然無法觸發drop事件。如需拖拽頁面里面的元素,需要給其添加屬性draggable="true"
          2. 獲取拖拽文件: 在 drop 事件觸發后通過e.dataTransfer.files獲取拖拽文件列表,一定要將drop的默認事件取消掉,否則會默認打開文件length屬性獲取文件數量,type屬性獲取文件類型
          3. 讀取圖片數據并添加預覽圖: 實例化FileReader對象,通過其readAsDataURL(file)方法獲取文件二進制流,并監聽其onload事件,將e.result賦值給img的src屬性,最后將圖片添加到DOM中
          4. 發送圖片數據
          <!DOCTYPE html>
          <html lang="zh-cn">
          <head>
            <meta charset="UTF-8">
            <meta name="viewport" content="width=device-width, initial-scale=1.0">
            <title>前端開發-拖拽上傳文件</title>
          </head>
          <body>
            
          <script>
          document.ondragover = (e) => {
            e.preventDefault()
          }
          document.ondrop = (e) => {
            e.preventDefault()
            // 某些版本的 Firefox 無視 preventDefault
            // 需要執行 stopImmediatePropagation 防止瀏覽器打開文件
            e.stopImmediatePropagation()
            const file = e.dataTransfer.files[0]
            const img = new Image()
            img.src = URL.createObjectURL(file)
            document.body.appendChild(img)
          
            console.log(file)
            // 如何上傳文件?
            // 參見 https://www.toutiao.com/article/7298667864926536242/
          }
          </script>
          
          </body>
          </html>

          要為大家詳細介紹了HTML5拖放效果的實現代碼,拖放即抓取對象以后拖到另一個位置。感興趣的小伙伴們可以參考一下:

          在 HTML5 中,拖放是標準的一部分,任何元素都能夠拖放。

          Internet Explorer 9+, Firefox, Opera, Chrome, 和 Safari 支持拖動。但 Safari 5.1.2不支持拖動。

          下面看看實現效果:

          拖拽前

          拖拽后

          代碼實現:

          把draggable屬性設置為true ,才能使元素可拖動。

          然后,規定當元素被拖動時,會發生什么。

          在上面的例子中,ondragstart 屬性調用了一個函數,drag(event),它規定了被拖動的數據。

          dataTransfer.setData() 方法設置被拖數據的數據類型和值:

          在這個例子中,數據類型是 "Text",值是可拖動元素的 id ("drag1")。

          ondragover 事件規定在何處放置被拖動的數據。

          默認地,無法將數據/元素放置到其他元素中。如果需要設置允許放置,我們必須阻止對元素的默認處理方式。

          這要通過調用 ondragover 事件的 event.preventDefault() 方法:event.preventDefault()

          當放置被拖數據時,會發生 drop 事件。

          在上面的例子中,ondrop 屬性調用了一個函數,drop(event):

          調用 preventDefault() 來避免瀏覽器對數據的默認處理(drop 事件的默認行為是以鏈接形式打開)

          通過 dataTransfer.getData("Text") 方法獲得被拖的數據。該方法將返回在 setData() 方法中設置為相同類型的任何數據。

          被拖數據是被拖元素的 id ("drag1")

          把被拖元素追加到放置元素(目標元素)中

          若要實現來回拖動:

          若要在兩個地方來回拖動,只需將上面代碼稍作修改就行了.將body中的代碼改成:

          然后在style樣式中加上#div2就可以了:


          主站蜘蛛池模板: 亚洲一区在线视频观看| 亚洲AV成人一区二区三区观看| 国产自产在线视频一区| 3d动漫精品啪啪一区二区中| 国产情侣一区二区三区| 一区在线免费观看| 日本一区二区三区在线视频观看免费 | 一区二区三区中文| 国产伦精品一区二区三区免.费| 无码毛片视频一区二区本码 | 国产成人一区二区动漫精品| 午夜福利国产一区二区| 丰满人妻一区二区三区视频| 国产日韩一区二区三免费高清| 国产精品视频一区二区噜噜| 国产精品视频一区二区噜噜| 亚洲无人区一区二区三区| 无码国产精品一区二区免费vr | 狠狠色婷婷久久一区二区| 亚洲a∨无码一区二区| 中文字幕国产一区| 免费一区二区无码东京热| 亚洲sm另类一区二区三区| 国产精品va一区二区三区| 亚洲一区精品视频在线| 无码一区二区三区免费视频| 久久精品综合一区二区三区| 日本亚洲国产一区二区三区| 福利片福利一区二区三区| 国产精品一级香蕉一区| 久久国产三级无码一区二区| 国产精品视频一区二区三区四| 伊人激情AV一区二区三区| 久久无码精品一区二区三区| 亚洲av无码一区二区三区人妖| 久久se精品一区精品二区国产 | 亚洲乱码av中文一区二区| 亚洲一区二区影院| 亚洲一区电影在线观看| 亚洲一区二区三区在线观看网站| 无码人妻视频一区二区三区|