小編今天又get到一個新技能,就是上傳圖片并顯示進度條,話不多說,直接進入正題!沖沖沖!!💪
實作效果:
當點擊上傳檔案按鈕后,如果未選擇檔案,會跳出請選擇要上傳的檔案提示框,反之,會有一個上傳圖片的進度條顯示,當上傳完成后,圖片也會對應的顯示在頁面中.

實作步驟:
① 定義UI 結構
② 驗證是否選擇了檔案
③ 向 FormData 中追加檔案
④ 使用 xhr 發起上傳檔案的請求
⑤ 監聽 onreadystatechange請求
⑥ 顯示檔案上傳進度
⑦ 基于 bootstrap 繪制進度條效果
⑧ 監聽上傳完整的事件
【接下來我會根據實作步驟來一一說明,最后會附上完整代碼,認真看喲~ 】
分步決議:
① 定義UI 結構
先引入相關的檔案,bootstrap.css 和 jQuery.min.js
開始布局頁面基本結構(代碼如下圖所示)
其中進度條的樣式是從bootstrap官網——>組件——>進度條中挑選的
最后給一個 Img 標簽用來顯示上傳到服務器的圖片
<!-- 檔案選擇框 -->
<input type="file" id="file1">
<button id="btn">上傳檔案</button>
<br>
<!-- 參考 bootstrap中的進度條 -->
<div class="progress" style="width: 500px; margin: 15px 10px">
<div class="progress-bar progress-bar-striped active"style="width: 0" id="percent">
0
</div>
</div>
<!--顯示上傳到服務器的圖片-->
<img src="" alt="" id="img" width="800">
② 驗證是否選擇了檔案
先獲取到上傳檔案的按鈕并為它添加點擊事件
獲取到選擇的檔案串列(files)
其中 var files = document.querySelector('#file1').files
通過id獲取檔案選擇框,在檔案選擇框中有一個 files 屬性,它是一個陣列,里面存放用戶 選擇的檔案,判斷 它的length是否小于等于0,如果是,則沒有選擇檔案
<script>
// 1.獲取上傳檔案的按鈕
var btn = document.querySelector('#btn')
// 2.為按鈕添加 click 事件監聽
btn.addEventListener('click',function(){
// 3.獲取到選擇的檔案串列
var files = document.querySelector('#file1').files
if(files.length <= 0) {
return alert('請選擇要上傳的檔案!')
}
}
</script>
③ 向 FormData 中追加檔案
Ajax 操作往往用來提交表單資料,為了方便表單處理,HTML5新增一個 formData 物件,可 以模擬表單操作
通過 append 就可以向 FormData 中追加檔案
//1. 創建 FormData 物件
var fd = new FormData()
//2. 向 FormData 中追加檔案,('自定義檔案名',檔案),因為是一個陣列,取第一個檔案所以索引為0
fd.append('avatar',files[0])
④ 使用 xhr 發起上傳檔案的請求
XMLHttpRequest(簡稱 xhr) 是瀏覽器提供的 Javascript 物件,通過它,可以 請求服務器上 的資料資源
創建完 xhr 物件后,通過呼叫 open 函式,指定 請求方式 與 URL地址
這里需要注意!因為是上傳檔案,所以請求方式必須為 post
呼叫 send 函式,發起 Ajax 請求
// 1. 創建 xhr 物件
var xhr = new XMLHttpRequest()
// 2. 呼叫 open 函式,指定請求型別與URL地址,其中,請求型別必須為 post
xhr.open('POST','http://www.liulongbin.top:3006/api/upload/avatar')
// 3. 發起請求
xhr.send(fd)
⑤ 監聽 onreadystatechange 請求
監聽 xhr 物件的 請求狀態 readyState; 與服務器的 回應狀態 status
如果 xhr.readyState 全等于 4 且 xhr.status 全等于 200 ,就獲取從服務器回應回來的資料,
并把它轉換為 JS 物件(方便后續獲取里面的值) 存放在 自定義的 data 物件中
獲取到的 data 資料中有很多的屬性,其中 data.status 代表上傳的狀態,如果為 200則表示上傳成功
如果上傳成功就把上傳的圖片顯示在頁面中
xhr 物件的 readyState 屬性
值 狀態 描述 0 UNSENT XMLHttpRequest 物件已被創建,但尚未呼叫 open() 方法 1 OPENED open() 方法已經被呼叫 2 HEADERS_RECEIVED send() 方法已經被呼叫,回應頭也已經被接收 3 LOADING 資料接收中,此時 response 屬性中已經包含部分資料 4 DONE Ajax 請求完成,這意味著資料傳輸已經徹底完成或失敗
xhr.onreadystatechange = function() {
if(xhr.readyState === 4 && xhr.status === 200) {
var data = JSON.parse(xhr.responseText)
if(data.status === 200) {
// 上傳成功
// 將服務器回傳的圖片地址,設定為 <img> 標簽的 src 屬性
document.querySelector('#img').src = 'http://www.liulongbin.top:3006' + data.url
} else {
// 上傳失敗
console.log('圖片上傳失敗!' + data.message);
}
}
}
⑥ 顯示檔案上傳進度
新版本的 XHLHttpRequest 物件中,可以通過監聽 xhr.upload.onprogress 事件,來獲取 到檔案的上傳進度
//做檔案上傳的進度
xhr.upload.onprogress = function(e) {
//e.lengthComputable 是一個布林值,表示當前上傳的資源是否具有可計算的長度
if(e.lengthComputable) {
// e.loaded 已傳輸的位元組
// e.total 需傳輸的總位元組
var percentComplete = Math.ceil((e.loaded/e.total) * 100)
}
}
⑦ 基于 bootstraps 繪制進度條效果
把算出的上傳進度的百分比賦值給從 bootstrap 中引入的模板中,從而實作將進度繪制到頁面
//將進度渲染到頁面
$('#percent').attr('style','width:' + percentComplete + '%;').html(percentComplete + '%')
⑧ 監聽上傳完整的事件
通過監聽 xhr.upload.onload 事件來表示檔案是否上傳完整,上傳完整后,將進度條修改為綠色
xhr.upload.onload = function() {
// 移除當前樣式,添加 新樣式
$('#percent').removeClass().addClass('progress-bar progress-bar-success')
}
完整代碼
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="../bootstrap.css">
<script src="../jQuery.min.js"></script>
</head>
<body>
<input type="file" id="file1">
<button id="btn">上傳檔案</button>
<br>
<!-- bootstrap中的進度條 -->
<div class="progress" style="width: 500px; margin: 15px 10px">
<div class="progress-bar progress-bar-striped active"style="width: 0" id="percent">
0
</div>
</div>
<img src="" alt="" id="img" width="800">
<script>
// 1.獲取上傳檔案的按鈕
var btn = document.querySelector('#btn')
// 2.為按鈕添加 click 事件監聽
btn.addEventListener('click',function(){
// 3.獲取到選擇的檔案串列
var files = document.querySelector('#file1').files
if(files.length <= 0) {
return alert('請選擇要上傳的檔案!')
}
//1. 創建 FormData 物件
var fd = new FormData()
//2. 向 FormData 中追加檔案
fd.append('avatar',files[0])
var xhr = new XMLHttpRequest()
//做檔案上傳的進度
xhr.upload.onprogress = function(e) {
//e.lengthComputable 是一個布林值,表示當前上傳的資源是否具有可計算的長度
if(e.lengthComputable) {
// e.loaded 已傳輸的位元組
// e.total 需傳輸的總位元組
var percentComplete = Math.ceil((e.loaded/e.total) * 100)
//將進度渲染到頁面
$('#percent').attr('style','width:' + percentComplete + '%;').html(percentComplete + '%')
}
}
xhr.upload.onload = function() {
$('#percent').removeClass().addClass('progress-bar progress-bar-success')
}
xhr.open('POST','http://www.liulongbin.top:3006/api/upload/avatar')
xhr.send(fd)
xhr.onreadystatechange = function() {
if(xhr.readyState === 4 && xhr.status === 200) {
var data = JSON.parse(xhr.responseText)
if(data.status === 200) {
// 上傳成功
// 將服務器回傳的圖片地址,設定為 <img> 標簽的 src 屬性
document.querySelector('#img').src = 'http://www.liulongbin.top:3006' + data.url
} else {
// 上傳失敗
console.log('圖片上傳失敗!' + data.message);
}
}
}
})
</script>
</body>
</html>
這次的分享到這就結束啦~大家快去試試把!

轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/351032.html
標籤:其他
上一篇:預處理,編譯,匯編,鏈接
