zoukankan      html  css  js  c++  java
  • 基于“formData批量上传的多种实现” 的多图片预览、上传的多种实现

      前言

      图片上传是web项目常见的需求,我基于之前的博客的代码(请戳:formData批量上传的多种实现)里的第三种方法实现多图片的预览、上传,并且支持三种方式添加图片到上传列表:选择图片、复制粘贴图片、鼠标拖拽图片,同时支持从上传列表中移除图片(点击“X”号)

      

      效果演示

      选择图片

      页面操作

      后台接参

      复制粘贴

      页面操作,使用Ctrl C、 V 效果也一样

      后台接参

       

       鼠标拖拽

      页面操作

      后台接参

      show the code

      代码与之前的博客变化不大,主要是将p标签换成了img标签并且调整好样式,input加入了格式校验,使用window.URL.createObjectURL进行图片的预览等等,更多细节请直接看对比之前的代码与现在的代码

      注:项目用到了bootstrap、layer、thymeleaf,需要先引入相关文件

      css

      注意:样式在父页面引入

          .nav-bar {
              border-top: 1px solid #9E9E9E;
              margin: 10px 0 20px;
          }
    
          .nav-bar-title {
              margin: -13px 0 0 35px;
              background-color: white;
              padding: 0 10px;
              float: left;
              color: #199ED8;
          }
    
            .images-remove {
                font-size: 25px;
                color: red;
                cursor: pointer;
                position: relative;
                right: 0px;
                top: -15px;
            }
    
            .images-text-img {
                float: left;
                height: 100px;
                width: 100px;
                border: 1px solid #c2cad8;
                margin-bottom: 5px;
            }
    
            .images-text-img + i {
                float: left;
                line-height: 30px !important;
            }
    
            .input-images {
                width: 90% !important;
                padding: 4px 12px !important;
            }
    
            .images-list {
                border: 1px solid #c2cad8;
                padding: 10px;
                width: 400px;
                height: 355px;
                overflow: auto;
            }

      imagesUpLoad.html

    <!DOCTYPE html>
    <html xmlns:th="http://www.thymeleaf.org">
    <body>
    <div th:fragment="imagesPage(applyId)">
        <div class="nav-bar"><span class="nav-bar-title">图片上传</span></div>
        <form th:applyId="${applyId}" class="form-horizontal images-form" enctype="multipart/form-data">
            <div class='form-body'>
                <div class='form-group'>
                    <div class="col-md-4">
                        <button type="button" class="btn btn-default images-btn" onclick="Images.appendImagesInput(this)">
                            选择图片
                        </button>
                    </div>
                </div>
                <div class='form-group'>
                    <div contenteditable class="images-list">
    
                    </div>
                </div>
            </div>
        </form>
    </div>
    </body>
    </html>

      js

      只需执行一次初始化函数即可

            var Images = {
                //初始化
                init:function(){
                    Images.removeImagesInputListener();
                    Images.pasteImagesListener();
                },
                //上传图片
                upload: function (applyId) {
                    //终止上传
                    if (!applyId) {
                        layer.msg('images applyid is null');
                        return;
                    }
                    //添加附件
                    var formData = new FormData();
                    $("form[applyId='" + applyId + "']").find("input[name='images']").each(function (index, element) {
                        //上传的时候,先看FileList,在看我们自定义的filess
                        if ($(element).val() || element.filess) {
                            formData.append("images", element.files.length ? element.files[0] : element.filess);
                        }
                    });
    
                    //追加applyId到formData
                    formData.append("applyId", applyId);
    
                    //执行上传
                    $.ajax({
                        url: ctx + "/upload",
                        type: "post",
                        data: formData,
                        processData: false,
                        contentType: false,
                        success: function (data) {
                            if (checkResult(data)) {
                                console.log('图片上传成功:', data);
    
                            }
                        },
                        error: function (e) {
                            console.log('图片上传失败');
                            throw e;
                        }
                    });
                },
                //添加待上传图片
                appendImagesInput: function (btn,file) {
                    //先追加html,input限制文件类型 可以直接写全,或者accept="image/*"
                    $(btn).parents('.images-form').find(".images-list").append("<div><input type="file" name="images" class="hidden" accept="image/gif,image/jpeg,image/jpg,image/png,image/svg"/></div>");
    
                    //最新追加的input
                    var images = $(btn).parents('.images-form').find(".images-list").find("input[name='images']");
    
                    if(file){
                        var  $input = images[images.length - 1];
                        /*
                            在 HTML 文档中 ,<input type="file"> 标签是浏览器向服务器发送选中文件的。该元素有一个 value 属性,保存了用户指定的文件的名称,
                            为安全起见,file-upload 元素的value 属性是只读的,不允许程序员修改它的值,并且HTML value 属性也会被忽略。
                            
    解决方法:我们定义一个自己的属性来存储file,上传的时候做处理
    */ $input.filess = file; var img = $("<img class='images-text-img' src=""/>"); img.attr("src", window.URL.createObjectURL(file)); $($input).parent("div").append(img).append("<i class="fa fa-times images-remove"></i>"); }else { //绑定input的change事件,注意:当我们点击取消或×号时并不触发,但是无所谓,我们在upload方法进行过滤空的input就可以了 images[images.length - 1].onchange = function () { var fileName = $(this).val(); if (fileName) { var img = $("<img class='images-text-img' src=""/>"); img.attr("src", window.URL.createObjectURL(this.files[0])); $(this).parent("div").append(img).append("<i class="fa fa-times images-remove"></i>"); } else { $(this).parent("div").remove(); } }; //触发最新的input的click images[images.length - 1].click(); } }, //删除待上传图片 removeImagesInputListener: function () { $("body").on("click", ".images-remove", function (even) { $(this).parent().remove(); }); }, //添加图片监听 pasteImagesListener: function () { //粘贴事件 document.addEventListener('paste', function (event) { if (event.clipboardData || event.originalEvent) { var clipboardData = (event.clipboardData || event.originalEvent.clipboardData); if (clipboardData.items) { paste("paste",clipboardData.items); } } }); //拖拽事件 document.addEventListener("dragenter", function (e) { e.stopPropagation(); e.preventDefault(); }, false); document.addEventListener("dragleave", function (e) { e.stopPropagation(); e.preventDefault(); }, false); document.addEventListener("dragover", function (e) { e.stopPropagation(); e.preventDefault(); }, false); document.addEventListener("drop", function (e) { e.stopPropagation(); e.preventDefault(); paste("drop",e.dataTransfer.files); }, false); var paste = function (type,files) { var items = files, len = items.length, blob = []; for (var i = 0; i < len; i++) { if (items[i].type.indexOf("image") !== -1) { //两种方式 if(type === "paste"){ blob.push(items[i].getAsFile()); }else if(type === "drop"){ blob.push(items[i]); } } } if (blob.length !== 0) { for (var i = 0; i < blob.length; i++) { Images.appendImagesInput($(".images-btn"),blob[i]) } } } } }; //调用初始化 Images.init();

      controller

        /**
         * 批量上传
         */
        @PostMapping("upload")
        public ResultModel<List<AttachmentVo>> upload(MultipartFile[] images, @RequestParam("applyId") String applyId) {
            System.out.println(images.length);
            System.out.println(applyId);
            return null;
        }

      父页面调用

      直接在需要上传组件的地方嵌入

                <div th:replace="attachment/imagesUpLoad::imagesPage(123456)"></div>

      调用上传方法

      直接在浏览器的控制台调用

    Images.upload("123456");

      后记

      还有一点不够完美的就是当我的页面出现多个上传组件时(情况参考之前博客了的新需求),通过复制粘贴、鼠标拖拽的方式时,调用Images.appendImagesInput追加html不好追加(目前是通过class去找),因为不好找到DOM对象,这里先暂时满足页面只有一个上传组件的情况,后面再进行升级

  • 相关阅读:
    hadoop常用命令详细解释
    2019-05-20 Sublime Text 编辑
    2019-05-20 什么是分布式系统、分布式锁
    2019-05-19 centos7下删掉一个目录下所有的文件
    2019-05-17 ABRT has detected 1 problem(s). For more info run: abrt-cli list --since 1558053651
    2019-05-17 java.net.BindException: Address already in use: JVM_Bind <null>:8083
    2019-05-16mysql忘记密码怎么办
    2019-05-16查看MySQL版本sql语句
    2019-05-15 cenots7动态IP地址改为静态
    2019-05-14 MySQL通过dos命令操作数据库
  • 原文地址:https://www.cnblogs.com/huanzi-qch/p/10186367.html
Copyright © 2011-2022 走看看