js 实现文件上传样式

  • A+
所属分类:Web前端
摘要

使用代码示例:项目目录如上图所示
如果要使用,只需要把js放入你的项目路径下,然后把img放到你的static目录(静态资源路径)。
这里js里面默认引入的图标是 ./ 的相对路径,请自行搜索然后进行更改为你项目的文件路径
上图项目示例为可直接打开查看的完整包,后文有下载地址

js 实现文件上传样式
js 实现文件上传样式
js 实现文件上传样式
js 实现文件上传样式

  • 这个js包括按钮样式,列表样式、带有删除、添加、放大(使用的是自带的放大功能,提供有API来放入你的弹窗来进行展示)
可监听的事件 Value wdaasd
onlargeClickCallBack 如果想使用自己的弹窗,只需要监听这个函数,拿到返回值给你的弹窗的img->href进行赋值即可 imgFile对象(包括这个被点击图片的全部信息)that(这个js的全局唯一对象,可以在这里面拿到你所有的值)
ondialogBeforeClose 自带的弹窗被关闭的回调 object 返回值是一个对象 对象.event -> 被执行的事件的源事件 对象.imgFile -> 被点击关闭弹窗时,目前弹窗上展示的图片对象信息
onaddImgList 每添加一个图片的回调 file -> 文件对象 that -> (这个js的全局唯一对象,可以在这里面拿到你所有的值)

创建对象的参数

参数 含义
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 实现文件上传样式" alt="">                     </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', 'mp3', 'word', 'pdf', 'ppt', 'excel', 'png', 'jpg'],      StopDialog: false,      showBtn: false  });  initHJFile(file); 

监听例子

//如果不想使用自带的弹窗,可以选择监听file对象的onlargeClickCallBack函数 file.callBack.onlargeClickCallBack = function (img, that) {} file.callBack.ondialogBeforeClose = function (event) {} file.callBack.onaddImgList = function () {} 

如何使用

js 实现文件上传样式

项目目录如上图所示
如果要使用,只需要把js放入你的项目路径下,然后把img放到你的static目录(静态资源路径)。
这里js里面默认引入的图标是 ./ 的相对路径,请自行搜索然后进行更改为你项目的文件路径
上图项目示例为可直接打开查看的完整包,后文有下载地址

源代码

此源代码为不包括图标的源代码,全部在一个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-list .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 实现文件上传样式" alt="">                     </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', 'mp3', 'word', 'pdf', 'ppt', 'excel', 'jpg', 'png'],                 // 是否阻止默认打开弹窗                 StopDialog: obj.StopDialog || false,                 // 弹窗的样式  宽 高                 shadeDialogStyle: obj.shade || [null, 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 实现文件上传样式" alt="">`;                         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 实现文件上传样式" alt="">`;                         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, that) => {},                 },                 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,             maxFileSize: 1024,             fileSuffix: ['mp4', 'mp3', 'word', 'pdf', 'ppt', 'excel', 'png', 'jpg'],             StopDialog: false,             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) {             console.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) {                 // 开启按钮模式                 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> 

链接:https://pan.baidu.com/s/1Te8Umgl24b0g7-wyCnydUw
提取码:6666