网站链接: 我爱捣鼓
当前位置: 首页 > 前端开发  > javascript

JavaScript实现多个图片上传删除功能的界面(含源码)

2021/12/1 21:58:22

前两天做项目,用JavaScript做了一个图片上传删除功能的界面,今天把它共享给大家,希望对你有所帮助,大家看了代码觉得有什么问题,也可以随时Q我。<!DOCTYPE html><html><head> <meta charset="UTF-8"> <meta http-equiv=&…

        前两天做项目,用JavaScript做了一个图片上传删除功能的界面,今天把它共享给大家,希望对你有所帮助,大家看了代码觉得有什么问题,也可以随时Q我。

<!DOCTYPE html>
<html>
<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="./fileUtils.css">
<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>
</head>
<body>
    <div>
        <div>
            <input type="file" file="">
            <div class="hj-box hj-append-item">
                <div class="append-item margin-class">
                    <div>
                        <img src="./img/push.png" alt="">
                    </div>
                </div>
            </div>
            <div class="hj-btn-box hj-hidden">
                <div>
                    选择图片
                </div>
            </div>
            <div>
            </div>
        </div>
    </div>
    <script>
        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 () {}
// 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.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="">`;
                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="">`;
                deleteDom.addEventListener('click', () => {
                    this.event.imgDeleteClick(id);
                })
                div.appendChild(largeDom);
                div.appendChild(deleteDom);
                this.dom.appendItemDom.appendChild(div);
                // 添加图片列表
                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;
            }
        }
}
// 加载初始信息,比如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>


查看在线实例


image.png

        通过以上内容我们知道了JavaScript实现多个图片上传删除功能的界面,感谢您访问“我爱捣鼓(www.woaidaogu.com)”网站的内容,希望对大家有所帮助!引用本文内容时,请注明出处!谢谢合作!

相关资讯

  • js如何遍历数组保存需要的

    我们如何通过遍历数组删除不需要的,保留需要的内容呢?我们来看看下面的代码是如何实现的。<!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml"><head> <title>js如何遍历数组保存需要的</title> <meta http-…

    2021/5/16 21:43:10
  • js写的urldecode函数及作用

    本函数对字符串进行URL解码。例如通过urlencode编码后的字符串,可通过UrlDecode进行解码。对Url路径加码的函数是UrlEncode 用法相反,和UrlDecode是一致对应的URLEncode是这样编码的 1、数字和字母不变。 2、空格变为"+"号。 3、其他被编码成&…

    2021/5/16 16:25:41
  • js getelementbyid后获取下一级的ID的方法

    根据id获取父对象,然后使用childNodes获取所有子对象数组,关键代码:document.getElementById(div_id).childNodes; // 子对象数组实现代码:<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xh…

    2021/5/9 13:28:27
  • javascript使用settimeout闭包实现倒计时

    闭包知识1、闭包的概念:指有权访问另一个函数作用域中的变量的函数,一般情况就是在一个函数中包含另一个函数。2、闭包的作用:访问函数内部变量、保持函数在环境中一直存在,不会被垃圾回收机制处理因为函数内部声明 的变量是局部的,只能在函数内部访问到,但是函数外…

    2021/4/24 19:56:28
  • js定时器setInterval清除之后还会执行

    今天在博客上看到有人问js定时器setInterval清除之后还会执行,他是js定时器控制一个盒子做旋转动画,离开页面后js定时器还在执行,但是盒子这个dom却被浏览器消除了,以至于再次进入该页面时动画会加速执行。解决方法 离开页面时清除定时器 进入时重新开启定时器d…

    2021/4/24 16:06:27
  • js添加删除表格table行列-附源码

    <!DOCTYPE htmlPUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-…

    2021/3/26 21:48:19
  • js如何判断页面某个元素是否已经绑定某个事件?

    我们有时防止页面元素重复绑定事件,需要判断一下页面对应的元素是否已经绑定了事件,下面就是我写了一个javascript函数用来判断页面某个元素是否已经绑定某个事件:javascript代码var div = document.getElementById(div);logEvent(click , div , false , false , funct…

    2021/3/24 21:20:27
  • A域名js访问B域名对象如何实现?JavaScript跨域解决办法

    什么是跨域JavaScript出于安全方面的考虑,不允许跨域调用其他页面的对象。但在安全限制的同时也给注入iframe或是ajax应用上带来了不少麻烦。这里把涉及到跨域的一些问题简单地整理一下:首先什么是跨域,简单地理解就是因为JavaScript同源策略的限制,a.com 域名下的js无…

    2021/3/11 22:44:58
  • js如何模拟手机平板移动设备--触摸、点击、滑屏(附源码)

    前一阵子公司做项目,手机上的网页需要js来模拟手机平板等移动设备的触摸、点击、滑屏效果,直接上代码,供大家参考(function(doc, win, undefined) { "use strict"; var start = { //记录开始的触点 x: 0, y: 0 }, …

    2021/2/28 22:08:08
  • 一张图教你彻底搞清楚javascript中的top、clientTop、scrollTop、offsetTop都是什么?

    clipboardscrollHeight: 获取对象的滚动高度。scrollLeft:设置或获取位于对象左边界和窗口中目前可见内容的最左端之间的距离scrollTop:设置或获取位于对象最顶端和窗口中可见内容的最顶端之间的距离scrollWidth:获取对象的滚动宽度offsetHeight:获取对象相对于版面或由父…

    2021/2/28 21:52:11