1、拖拽獲取到文件 a). 原理調用原生js提供的 drop系列的事件html
function clearDefault (event) { var e = event || window.event e.preventDefault() } document.addEventListener('dragentetr', clearDefault) document.addEventListener('dragleave', clearDefault) document.addEventListener('drop', clearDefault) document.addEventListener('dragover', clearDefault)
b). 在dom上指定一個區域做爲咱們要拖入文件的區域。通常是一個div;jquery
<div id="dropBox"></div>
爲改div綁定上事件,web
var div = document.querySelector('#dropBox') div.addEventListener('dragenter', function (event) { var e = event || window.event e.preventDefault() this.innerHTML = '請釋放鼠標' this.style.borderColor = 'green' }) div.addEventListener('dragleave', function (event) { var e = event || window.event e.preventDefault() this.style.borderColor = 'red' this.innerHTML = '請將文件拖在此區域' }) div.addEventListener('drop', function (event) { var e = event || window.event e.preventDefault() var files = e.dataTransfer.files // 這個是一個索引數組 => [file1, file2] // 每一個file擁有如下信息 注意: 它們都是隻讀的 var file = { lastModified: 1500618905073, // =>這個表明是最後修改時間 格式是時間戳 lastModifiedDate: 'Fri Jul 21 2017 14:35:05 GMT+0800 (中國標準時間)', // =>一樣也是最後修改的時間 格式是Date形式 name: '測試文檔.docx', // =>文件的名字 size: 969331, // =>文件的大小 單位是B 若有須要的話, 須要換算爲別的單位 type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', // =>文件的類型 webkitRelativePath: ''// => MDN上面說 它返回 File 相關的 path 或 URL。 } // 這裏咱們只是單文件上傳, 只取files中第一個文件 file = files[0] // 獲取文件的路徑採用的是另一個方法 window.URL.createObjectURL(file) 它的做用是建立一個能夠被瀏覽器識別的路徑 是一個網絡地址形式的路徑信息 var filePath = window.URL.createObjectURL(file) // 根據上面說的咱們在控制檯打印文件的信息 console.log('文件名: ' + file.name) console.log('大小: ' + bytesToSize(file.size)) console.log('類型: ' + file.type) console.log('路徑: ' + filePath) /* *到這裏已經獲取到了文件, 可使用ajax *上傳到服務器, 也可使用H5的 *FileReader *讀取它的內容 */ }) /* *在網上找的換算字節的函數 *參數: bytes number 待轉換的數字 *輸出: 合理的計算後並輸出單位 B KB MB... */ function bytesToSize (bytes) { if (bytes === 0) return '0 B' var k = 1000 // or 1024 var sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'] var i = Math.floor(Math.log(bytes) / Math.log(k)) return (bytes / Math.pow(k, i)).toPrecision(3) + ' ' + sizes[i] }
2、XMLHttpRequest Level 2 XMLHttpRequest Level 2 我喜歡叫它ajax2代 它與第一代相比增長了不少實用的東西這裏不作詳細說明ajax
// 建立一個ajax對象 var xhr = new XMLHttpRequest() xhr.open('GET', 'test.do') xhr.send()
獲取數據傳輸進度信息 上傳於下載調用的是不用對象的onprogress事件 上傳觸發的是xhr.upload對象的 onprogress事件 下載觸發的是xhr對象的onprogress事件chrome
xhr.onprogress = updateProgress xhr.upload.onprogress = updateProgress function updateProgress (event) { if (event.lengthComputable) { // event.loaded 已經發送 / 下載的數據量 // event.total 文件的總數據量 var completedPercent = event.loaded / event.total console.log(completedPercent) } } /* * 還有一些對應的事件, 這裏只提一下 * load事件:傳輸成功完成。 * abort事件:傳輸被用戶取消。 * error事件:傳輸中出現錯誤。 * loadstart事件:傳輸開始。 * loadEnd事件:傳輸結束,可是不知道成功仍是失敗。 */
timeout 請求超時的相關設置json
xhr.timeout = 5000 // 單位ms xhr.ontimeout = function () { // 請求發起後的5s內爲完成 就會結束請求並觸發該事件 console.log('請求錯誤') }
3、FormData 說明 在之前咱們的開發中, 獲取一個form的input的值時 採用本身定義一個json 鍵爲與後端定義好的name, 值爲用jquery選擇器找到對應的input,用val()方法獲取值。 如今有了FormData之後咱們不須要用jquery去獲取一個input的val()值, 像下面這樣: 在html中寫一個form表單後端
<form id="submit" action="http://test"> <input type="text" name="username"> <input type="text" name="pwd"> <input type="submit" value="提交"> </form>
在js中咱們這樣寫跨域
var submit = document.querySelector('#submit') // 獲取到id是submit的表單 submit.onsubmit = function () { var data = new FormData(submit) // 初始化一個formdata對象 /* * 這裏咱們已經獲取到了id爲submit中全部input的值 * 此時咱們console.log(data)的話在控制檯只能看到一個空對象。 * 這裏咱們用ajax發起請求的時候,在chrome的控制檯的network選項卡中能夠看到它內部的東西 */ // 若是須要在data中臨時加一個值的時候能夠這樣的形式加入 // data.append('name', 'value') data.append('enail', '345565@qq.com') }
如今就能夠上傳我在上邊拖拽拿到的文件了數組
function ajaxPushFile (file) { // 這裏的file就是上面咱們獲取到的file if (!file) { return false } var data = new FormData() // 初始化一個formdata對象 這裏沒有from元素就不傳值 data.append('files', file) // 將文件加入formdata中 var xhr = new XMLHttpRequest() // 初始化ajax xhr.open('POST', 'http://test') xhr.timeout = 10000 // 設置超時 xhr.responseType = 'text' // 設置響應返回的數據格式 xhr.onreadystatechange = function (e) { if (this.readyState === 4 && this.status === 200) { // 獲取返回的值 } } xhr.ontimeout = function () { // 超時的回調 alert('上傳失敗') } xhr.upload.onprogress = updateProgress // 獲取上傳進度 function updateProgress (event) { if (event.lengthComputable) { // event.loaded 已經發送 / 下載的數據量 // event.total 文件的總數據量 var completedPercent = event.loaded / event.total console.log(completedPercent) } } xhr.send(data) }
到此 拖拽功能完成 這個功能用到了拖拽事件 與 ajax2 與 FormData 技術點瀏覽器
頁面所有代碼:
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <style> * { margin: 0; padding: 0; } #drop { width: 500px; height: 400px; border: 10px dotted red; } </style> <body> <div id="drop"> 請將文件拖拽到這裏 </div> </body> <script> function clearDefault(event) { var e = event || window.event e.preventDefault() } document.addEventListener('dragentetr', clearDefault) document.addEventListener('dragleave', clearDefault) document.addEventListener('drop', clearDefault) document.addEventListener('dragover', clearDefault) var div = document.querySelector('#drop') div.addEventListener('dragenter', function(event) { var e = event || window.event e.preventDefault() this.innerHTML = '請釋放鼠標' this.style.borderColor = 'green' }) div.addEventListener('dragleave', function(event) { var e = event || window.event e.preventDefault() this.style.borderColor = 'red' this.innerHTML = '請將文件拖在此區域' }) div.addEventListener('drop', function(event) { var e = event || window.event e.preventDefault() var files = e.dataTransfer.files // 這個是一個索引數組 => [file1, file2] // 每一個file擁有如下信息 注意: 它們都是隻讀的 var file = { lastModified: 1500618905073, // =>這個表明是最後修改時間 格式是時間戳 lastModifiedDate: 'Fri Jul 21 2017 14:35:05 GMT+0800 (中國標準時間)', // =>一樣也是最後修改的時間 格式是Date形式 name: '測試文檔.docx', // =>文件的名字 size: 969331, // =>文件的大小 單位是B 若有須要的話, 須要換算爲別的單位 type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', // =>文件的類型 webkitRelativePath: '' // => MDN上面說 它返回 File 相關的 path 或 URL。 } // 這裏咱們只是單文件上傳, 只取files中第一個文件 file = files[0] // 獲取文件的路徑採用的是另一個方法 window.URL.createObjectURL(file) 它的做用是建立一個能夠被瀏覽器識別的路徑 是一個網絡地址形式的路徑信息 var filePath = window.URL.createObjectURL(file) // 根據上面說的咱們在控制檯打印文件的信息 console.log('文件名: ' + file.name) console.log('大小: ' + bytesToSize(file.size)) console.log('類型: ' + file.type) console.log('路徑: ' + filePath) /* *到這裏已經獲取到了文件, 可使用ajax *上傳到服務器, 也可使用H5的 *FileReader *讀取它的內容 */ }) /* *在網上找的換算字節的函數 *參數: bytes number 待轉換的數字 *輸出: 合理的計算後並輸出單位 B KB MB... */ function bytesToSize(bytes) { if (bytes === 0) return '0 B' var k = 1000 // or 1024 var sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'] var i = Math.floor(Math.log(bytes) / Math.log(k)) return (bytes / Math.pow(k, i)).toPrecision(3) + ' ' + sizes[i] } function ajaxPushFile (file) { // 這裏的file就是上面咱們獲取到的file if (!file) { return false } var data = new FormData() // 初始化一個formdata對象 這裏沒有from元素就不傳值 data.append('files', file) // 將文件加入formdata中 var xhr = new XMLHttpRequest() // 初始化ajax xhr.open('POST', 'http://test') xhr.timeout = 10000 // 設置超時 xhr.responseType = 'text' // 設置響應返回的數據格式 xhr.onreadystatechange = function (e) { if (this.readyState === 4 && this.status === 200) { // 獲取返回的值 } } xhr.ontimeout = function () { // 超時的回調 alert('上傳失敗') } xhr.upload.onprogress = updateProgress // 獲取上傳進度 function updateProgress (event) { if (event.lengthComputable) { // event.loaded 已經發送 / 下載的數據量 // event.total 文件的總數據量 var completedPercent = event.loaded / event.total console.log(completedPercent) div.innerHTML = '已完成: ' + (completedPercent * 100) + '%' } } xhr.send(data) } </script> </html>