js 實現檔案上傳樣式詳情
阿新 • • 發佈:2021-10-22
目錄
- 1、概述
- 2、建立物件的引數
- 3、監聽例子
- 4、使用方法
- 5、原始碼
1、概述
這個包括按鈕樣式,列表樣式、帶有刪除、新增、放大(使用的是自帶的放大功能,提供有API來放入你的彈窗來進行展示)
可監聽的事件 | Value | wdaasd |
---|---|---|
onlargeClickCallBack | 如果想使用自己的彈窗,只需要監聽這個函式,拿到返回值給你的彈窗的img->href進行賦值即可 | imgFile物件(包括這個被點選圖片的全部資訊)that(這個js的全域性唯一物件,可以在這裡面拿到你所有的值) |
ondialogBeforeClose | 自帶的彈窗被關閉的回撥 | object 返回值是一個物件 物件.event -> 被執行的事件的源事件 物件.imgFile -> 被點選關閉彈窗時,目前彈窗上展示的圖片物件資訊 |
onaddImgList | 每新增一個圖片的回撥 | file -> 檔案物件 that -> (這個js的全域性唯一物件,可以在這裡面拿到你所有的值) |
2、建立物件的引數
引數 | 含義 |
---|---|
maxFileLength | 最大可以存在的檔案個數 預設值:2 |
maxFileSize | 每個檔案單獨最大的檔案大小 預設值:1024 (1M) |
fileSuffix | 允許上傳的檔案字尾 預設值:['mp4','mp3','word','pdf','ppt','excel','jpg','png'] |
StopDialog | 是否阻止開啟自帶的預設彈窗 預設值:false |
shadeDialogStyle | 如果開啟自帶彈窗的選項,那麼這個控制開啟的彈窗高寬多少預設值:[null,null],預設為null為自適應,如果想要設定百分比和px 請直接改變陣列[0,1],陣列第一項代表寬,第二項代表高 |
showBtnImgStyle | 是否開啟按鈕樣式 預設值:false |
使用程式碼示例:
<div class="hj-file"> <input type="file" file="" class="hj-file-input"> <div class="hj-box hj-append-item"> <div class="append-item margin-class"> <div class="img-push"> <img src="./img/push.png" alt="js 實現檔案上傳樣式詳情"> </div> </div> </div> <!-- 在不開啟按鈕樣式時,這個外層div可以刪除 --> <div class="hj-btn-box hj-hidden"> <div class="hj-btn"> 選擇圖片 </div> </div> <!-- 檔案資訊列表 --> <div class="hj-file-list"> </div> </div> var file = new File({ maxFileLength: 2,maxFileSize: 1024,fileSuffix: ['mp4','png','jpg'],StopDialog: false,showBtn: false }); initHJFile(file);
3、監聽例子
//如果不想使用自帶的彈窗,可以選擇監聽file物件的onlargeClickCallBack函式 file.callBack.onlargeClickCallBack = function (img,that) {} file.callBack.ondialogBeforeClose = function (event) {} file.callBack.onaddImgList = function () {}
4、使用方法
專案目錄如上圖所示
如果要使用,只需要把js
放入你的專案路徑下,然後把img
放到你的static
目錄(靜態資源路徑)。
這裡js裡面預設引入的圖示是 ./ 的相對路徑,請自行搜尋然後進行更改為你專案的檔案路徑
上圖專案示例為可直接開啟檢視的完整包,後文有下載地址
5、原始碼
此原始碼為不包括圖示的原始碼,全部在一個html頁面裡面
<!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> </head> <style> * { padding: 0; margin: 0; } body { width: 100vw; height: 100vh; /* display: flex; justify-content: center; align-items: center; */ } /* .box { width: 600px; } */ .hj-file { width: 100%; /* height: 100%; */ } .hj-file-input { display: none; } .hj-box { display: flex; flex-wrap: wrap; } .append-item { width: 150px; height: 150px; border: 1px dashed #b1b5bb; border-radius: 5px; background-color: #fbfdff; display: flex; align-items: center; margin: 10px; justify-content: center; } .image-item { width: 150px; height: 150px; border-radius: 5px; margin: 10px; display: flex; justify-content: center; align-items: center; border: 1px solid #eaedf1; position: relative; background-size: 100% 100%; background-repeat: no-repeat; transition: 1s; animation: translaters 1s; } .image-item-delete { animation: bottom-translaters .7s; } @keyframes translaters { 0% { opacity: .2; transform: translate(0,-50%); } 100% { opacity: 1; transform: translate(0); } } @keyframes bottom-translaters { 0% { opacity: 1; transform: translate(0,0); } 100% { opacity: .2; transform: translate(0,50%); } } .img-push img { width: 60px; height: 60px; } .append-item:hover { border-color: #00d2fc; } .margin-class { margin-bottom: 20px; } .first { background-image: url('./img/66.jpg'); } .z-index-promote { z-index: 3; } .largeImg img { cursor: pointer; width: 30px; height: 30px; transition: .6s; display: none; } .deleteImg img { cursor: pointer; width: 40px; height: 40px; display: none; } .image-item:hover::before { content: ""; z-index: 2; background-color: #42393999; width: 100%; position: absolute; height: 100%; border-radius: 5px; transition: .6s; animation: transparency linear .6s; } .image-item:hover .largeImg img { display: block; animation: transparency linear .6s; } .image-item:hover .deleteImg img { display: block; animation: transparency linear .6s; } @keyframes transparency { 0% { opacity: 0; } 100% { opacity: 1; } } .hj-shade { width: 100vw; height: 100vh; background-color: #302d2d99; position: fixed; overflow: hidden; z-index: 1978; display: flex; left: 50%; top: 50%; transform: translate(-50%,-50%); justify-content: center; align-items: center; animation: hj-shade-sacle .5s; } @keyframes hj-shade-sacle { 0% { transform: translate(-50%,-50%) scale(0%); } 100% { transform: translate(-50%,-50%) scale(100%); } } @keyframes hj-shade-hidden { 0% { transform: translate(-50%,-50%) scale(100%); } 100% { transform: translate(-50%,-50%) scale(0%); } } .hj-shade-hidden { animation: hj-shade-hidden .5s; } .hj-shade { overflow: auto; } .hj-shade .hj-box { width: 60%; height: 80%; padding: 20px 10px 10px 10px; background-size: 100% 100%; background-color: white; } .hj-shade .hj-box .hj-img { width: 100%; overflow: auto; height: 100%; } .hj-file-list .hj-file-list-item { background-color: white; color: #8cacb3; display: flex; line-height: 2; font-size: 0.8em; } .hj-file-list .hj-file-list-item:hover { background-color: #00d2fc70; color: white; } .hj-file-list .hj-file-list-item .hj-left { width: 30%; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; } .hj-file-list .hj-file-list-item .hj-left span { margin-left: 20px; cursor: pointer; } .hj-file-list .hj-file-list-item .hj-right { width: 30%; display: flex; align-items: center; justify-content: end; } .hj-file-listwww.cppcns.com .hj-file-list-item .hj-right span { margin-right: 20px; } .hj-file-list .hj-file-list-item .hj-right img { width: 20px; height: 20px; cursor: pointer; } @keyframes hj-list-hidden { 0% { opacity: 1; } 100% { opacity: 0; } } .hj-list-hidden { animation: hj-list-hidden .7s; } .hj-btn-box { margin-bottom: 25px; } .hj-btn-box .hj-btn { margin-left: 20px; cursor: pointer; background-color: #009efa; width: 30%; line-height: 2; border-radius: 4px; color: white; font-size: 1.2em; text-align: center; } .hj-hidden { display: none; } </style> <body> <div class="box"> <div class="hj-file"> <input type="file" file="" class="hj-file-input"> <div class="hj-box hj-append-item"> <div class="append-item margin-class"> <div class="img-push"> <img src="./img/push.png" alt="js 實現檔案上傳樣式詳情"> </div> </div> </div> <div class="hj-btn-box hj-hidden"> <div class="hj-btn"> 選擇圖片 </div> </div> <div class="hj-file-list"> </div> </div> </div> <script> // File建構函式 function File(obj) { // 檔案總個數 this.fileLength = 0; // 檔案陣列 this.fileList = []; // 物件引數配置檔案 this.config = { // 最大檔案個數 maxFileLength: obj.maxFileLength || 2,// 最大檔案大小 maxFileSize: obj.maxFileSize || 1024,// 允許的檔案字尾 fileSuffix: obj.fileSuffix || ['mp4','png'],// 是否阻止預設開啟彈窗 StopDialog: obj.StopDialog || false,// 彈窗的樣式 寬 高 shadeDialogStyle: obj.shade || [null,// 是否開啟按鈕樣式 showBtnImgStyle: obj.showBtn || false,}; // fileDom中儲存的唯一的dom節點 this.dom = { // input 檔案選中輸入框dom inputDom: null,// append-item 新增點選dom imageItemDom: null,// 要向hj-append-item節點後面追加圖片的dom appendItemDom: null,// 要向hj-file-list節點後面新增圖片列表的dom appendListDom: null,}; // 事件處理物件 this.event = { // append-item點選事件處理 imageItemClick: () => { this.dom.inputDom.click(); },// input 檔案選中輸入框選擇完圖片之後事件處理 changeLoadFile: (file) => { this.method.filterFile(file.target.files); },// 圖片刪除事件 imgDeleteClick: (id) => { for (let index = 0; index < this.fileList.length; index++) { if (this.fileList[index].id == id) { let _before = this.fileList.slice(0,index == this.fileList.length ? index - 1 : index); let _after = this.fileList.slice(index + 1); _before = _before.concat(_after); // 刪除圖片 this.method.deleteImg(id); setTimeout(() => { this.fileList[index].dom.remove(); this.fileList[index].listDom.remove(); this.fileLength--; this.fileList = _before; },600); break; } } 1 },// 圖片放大事件 imgLargeClick: (id) => { let imgFile = this.privateUtils.foreachFileListToId(id); console.log(imgFile); this.callBack.onlargeClickCallBack(imgFile,this); if (this.config.StopDialog) return; let hjShadeDiv = document.getElementsByClassName('hj-shade'); if (hjShadeDiv.length != 0) return; let div = document.createElement('div'); div.className = 'hj-shade'; let div2 = document.createElement('div'); div2.className = 'hj-box'; let img = document.createElement('img'); img.className = 'hj-img'; img.src = imgFile.base64; div2.appendChild(img); div.addEventListener('click',(event) => { this.callBack.ondialogBeforeClose({ event: event,imgFile: imgFile,}); div.className = div.className + ' hj-shade-hidden'; setTimeout(() => { document.body.removeChild(div); },500); }) // 防止在按鈕模式下,會出現第一次沒有載入完成,高長為0的不正常情況 img.onload = () => { div.appendChild(div2); document.body.appendChild(div); this.privateUtils.computeDialogWH(img,div2); } },},this.method = { // 過濾圖片 filterFile: (list) => { for (let index = 0; index < list.length; index++) { let size = parseInt(list[index].size / 1024); let suffix = list[index].name.substring(list[index].name .lastIndexOf('.') + 1); // 是否符合字尾 let isTrue = false; // 判斷檔案大小 if (size > this.config.maxFileSize) { console.log("檔案太大"); break; } for (let j = 0; j < this.config.fileSuffix.length; j++) { if (suffix == this.config.fileSuffix[j]) { isTrue = true; break; } } if (isTrue) { let id = parseInt(Math.random() * 100000); this.fileList.push({ id: id,file: list[index],base64: '',dom: '',listDom: '',}); console.log(this.fileList); this.method.streamToImgBase64(list[index],id); } else { console.log("檔案字尾不符合"); } } },// 處理圖片展示 streamToImgBase64: (file,id) => { var fileReader = new FileReader(); fileReader.onload = (data) => { this.method.appendImage(data.target.result,id); } fileReader.readAsDataURL(file); },// 追加圖片到dom節點中 appendImage: (url,id) => { let div = document.createElement('div'); div.className = 'image-item margin-class'; div.style.backgroundImage = 'url(' + url + ')'; for (let index = 0; index < this.fileList.length; index++) { if (this.fileList[index].id == id) { this.fileList[index].dom = div; this.fileList[index].base64 = url; break; } } // 建立刪除dom,全部使用addEventListener let largeDom = document.createElement('div'); largeDom.className = 'largeImg z-index-promote'; largeDom.innerHTML = `<img src="./img/big.png" alt="js 實現檔案上傳樣式詳情">`; largeDom.addEventListener('click',() => { this.event.imgLargeClick(id); }) let deleteDom = document.createElement('div'); deleteDom.className = 'deleteImg z-index-promote'; deleteDom.innerHTML = `<img src="./img/delete.png" alt="js 實現檔案上傳樣式詳情">`; deleteDom.addEventListener('click',() => { this.event.imgDeleteClick(id); }) div.appendChild(largeDom); div.appendChild(deleteDom); this.dom.appendItemDom.appendChild(div); this.fileLength++; // 新增圖片列表 this.method.addImgList(id); },// 刪除圖片 deleteImg: (id) => { for (let index = 0; index < this.fileList.length; index++) { if (this.fileList[index].id == id) { let item = this.fileList[index]; let cless = item.dom.getAttribute('class'); let clessList = item.listDom.getAttribute('class'); this.fileList[index].dom.setAttribute("class",cless + " image-item-delete"); this.fileList[index].listDom.setAttribute("class",clessList + " hj-list-hidden ") break; } } },// 新增圖片列表 addImgList: (id) => { let file = this.privateUtils.foreachFileListToId(id); this.callBack.onaddImgList(file,this); let div = document.createElement('div'); div.className = ' hj-file-list-item ' let div$left = document.createElement('div'); let div$right = document.createElement('div'); let file$img = document.createElement('img'); let fileSize = this.privateUtils.computeFileSize(file.file.size); file$img.src = './img/delete-balck.png'; div$left.className = ' hj-left '; div$right.className = ' hj-right '; div$left.innerHTML = `<span>${file.file.name}</span>` div$right.innerHTML = `<span>${fileSize}</span>`; div$left.addEventListener('click',() => { this.event.imgLargeClick(id); }) file$img.addEventListener('click',() => { this.event.imgDeleteClick(id); }) div$right.appendChild(file$img); div.appendChild(div$left); div.appendChild(div$right); for (let index = 0; index < this.fileList.length; index++) { if (id == this.fileList[index].id) { this.fileList[index].listDom = div; break; } } this.dom.appendListDom.appendChild(div); },} // 暴露的監聽Api this.callBack = { // 阻止預設自帶的開啟彈窗 onlargeClickCallBack: (img,that) => {},// 自帶的彈窗被關閉時的回撥 // {event: 點選的源事件物件 imgFile: 被關閉的那張圖片的全域性file物件資訊} ondialogBeforeClose: (object) => {},// 每一次新增圖片列表時的回撥 onaddImgList: (file,this.privateUtils = { foreachFileListToId: (id) => { for (let index = 0; index < this.fileList.length; index++) { if (id == this.fileList[index].id) { return this.fileList[index]; } } },computeFileSize: (size) => { let result = parseInt(size / 1024); if (result < 1024) { return result + '.KB'; } else if (result >= 1024) { return parseInt(result / 1024) + ".MB"; } },// 計算彈窗的高度和長度 computeDialogWH: (img,dom) => { let w = this.config.shadeDialogStyle[0]; let h = this.config.shadeDialogStyle[1]; let w2 = img.naturalWidth; let h2 = img.naturalHeight; if (w2 > window.innerWidth * 0.9) { w2 = window.innerWidth * 0.7; h2 = window.innerHeight * 0.7; } dom.style.width = w == null ? w2 + "px" : w; dom.style.height = h == null ? h2 + "px" : h; } } } var file = new File({ maxFileLength: 2,showBtn: false }); initHJFile(file); // 如果不想使用自帶的彈窗,可以選擇監聽file物件的onlargeClickCallBack函式 file.callBack.onlargeClickCallBack = function (img,that) {} file.callBack.ondialogBeforeClose = function (event) {} file.callBack.onaddImgList = function () {} // 載入初始資訊,比如dom節點的新增 function initHJFile(file) { conshttp://www.cppcns.comole.log(file); let input_dom = document.getElementsByClassName('hj-file-input')[0]; let imageItem_dom = document.getElementsByClassName('append-item')[0]; let appendItem_dom = document.getElementsByClassName('hj-append-item')[0]; let appendList_dom = document.getElementsByClassName('hj-file-list')[0]; file.dom.inputDom = input_dom; file.dom.imageItemDom = imageItem_dom; file.dom.appendListDom = appendList_dom; if (file.config.showBtnImgStyle) { www.cppcns.com // 開啟按鈕模式 appendItem_dom.style.display = 'none'; let btn = document.getElementsByClassName('hj-btn-box'); console.log(btn); if (btn.length != 0) { btn[0].className = 'hj-btn-box'; btn[0].children[0].addEventListener('click',file.event.imageItemClick); } else { console.log("沒有找到btn Class"); throw new Error('未定義按鈕模式所需的HTML') } } file.dom.appendItemDom = appendItem_dom; file.dom.imageItemDom.addEventListener('click',file.event.imageItemClick); file.dom.inputDom.addEventListener('change',file.event.changeLoadFile) } </script> </body> </html>
到此這篇關於js 實現檔案上傳樣式詳情的文章就介紹到這了,更多相關js 實現檔案上傳樣式內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!