类微信多图片上传

作者: kerush | 来源:发表于2017-07-05 13:12 被阅读117次
    前端入坑纪 30

    今天项目中碰到如题的效果。讲真,我的内心是拒绝的。
    原因还是input file 文件上传 这个按钮的锅。

    一直到目前为止,都没搜索和咨询到,如何取得input file 的取消事件。就是用户点了上传文件,选着选着,最后点了取消。貌似只能间接的通过onchange 来判定value,然后确定是否为空,也就是取消的状态。

    可是,这样得第一次点了,它取消了。第二次再点,才好识别出onchange是空的。简单说就是要点两次,这样的话,并不适合我目前这个项目的需求。

    如果这段文字让你看得云里雾里,那就请直接看下面的项目正文吧!

    上代码才是真理,其他都是浮云!

    真实项目效果图

    OK,first things first!项目链接

    HTML 结构
        <div class="infoEdt">
            <div class="clear">
                <label class="fl">姓名</label><input type="text" class="fr" placeholder="冯燕">
            </div>
            <div class="clear" style="border:none">
                <label class="fl">联系方式</label><input type="text" class="fr" placeholder="135662454777">
            </div>
        </div>
        <div class="imgUps">
            <p class="clear">
                <span class="fl">图片上传</span><span class="fr" style="color:#999">最多上传10张图</span>
            </p>
            <form id="formImg">
                <section id="divElesWrp" class="clear">
                    <a id="addPic" class="fl" href="javascript:;"></a>
                </section>
                <a class="upsBtn" href="javascript:;" id="bmBtn">确认报名</a>
            </form>
        </div>
    

    请忽略上面的input框,和本文的效果无关,您看看就好。

    CSS 结构
            /*rest style*/
            
            body {
                padding: 0;
                margin: 0;
                background-color: #f4f4f4;
                max-width: 640px;
                margin: 0 auto;
            }
            
            p {
                padding: 0;
                margin: 0;
            }
            
            ul,
            li {
                padding: 0;
                margin: 0;
                list-style: none;
            }
            
            a {
                text-decoration: none;
                color: #525252;
            }
            
            img {
                vertical-align: middle;
            }
            
            input,
            button {
                outline: none;
                background: none;
                border: none;
            }
            
            .fl {
                float: left;
            }
            
            .fr {
                float: right;
            }
            
            .clear::after {
                display: block;
                content: "";
                clear: both;
            }
            /*page style*/
            
            .infoEdt {
                background-color: #fff;
                padding: 0 2%;
                margin-bottom: 6px;
            }
            
            .imgUps section {
                background-color: #fff;
                padding: 2% 1% 6%;
                width: 98%;
            }
            
            .imgUps p {
                padding: 0 2%;
                line-height: 40px;
                background-color: #fff;
            }
            
            .infoEdt div {
                font-size: 14px;
                line-height: 45px;
                color: #000;
                border-bottom: 1px solid #dfdfdf
            }
            
            .infoEdt input {
                line-height: 45px;
                text-align: right
            }
            
            .imgUps span {
                font-size: 15px;
                color: #000;
            }
            
            .imgUps form div {
                position: relative;
                width: 0;
                height: 0;
                background-color: #f3f3f3;
                padding: 12%;
                margin: 1% .5%;
                float: left;
                background-size: 100% auto;
                background-position: center center;
                background-repeat: no-repeat
            }
            
            .imgUps form div>em {
                display: block;
                position: absolute;
                border-radius: 50%;
                height: 26px;
                width: 26px;
                font-style: normal;
                color: #fff;
                line-height: 30px;
                text-align: center;
                top: 0;
                right: 0;
                background-color: #f3557b;
                background-image: url('wrap/img/loginBack.png');
                background-size: 47% auto;
                background-position: center center;
                background-repeat: no-repeat
            }
            
            #addPic {
                display: block;
                height: 0;
                width: 0;
                padding: 12%;
                margin: 1% .5%;
                float: left;
                background-image: url('wrap/img/addPic.png');
                background-size: 100% 100%;
                background-position: center center;
                background-repeat: no-repeat
            }
            
            .upsBtn {
                display: block;
                background-image: linear-gradient(-132deg, #f3557b 0%, #fa7157 100%);
                border-radius: 9px;
                width: 92%;
                text-align: center;
                margin: 6% 4%;
                line-height: 45px;
                font-size: 18px;
                color: #ffffff;
            }
    

    添加的图片是会显示为 .imgUps 里 form 内的 div 的背景,每个div是浮动布局的。同时,添加的按钮#addPic也是浮动的。点完后自动生成的input,故意注释了隐藏,以便后台查看。

    JS 结构
            var oUpBtn = document.getElementById("addPic");
            var oform = document.getElementById("formImg");
            var odWrp = document.getElementById("divElesWrp");
            var obmBtn = document.getElementById("bmBtn");
            var i = 0;// 为新添加的元素加id时,自动加上i
    
    
            // 这里的原理在 11篇《图片上传之在线预览》讲过,基本类似,就不赘述了
            function imgChange(ths) {
                var oinpt = ths;
                var freader = new FileReader();
                var ofile = oinpt.files[0];
                if (ofile) {
                    freader.readAsDataURL(ofile);
                    freader.onload = function() {
                        var newNode = document.createElement("div");
                        var spanEm = document.createElement("em");
                        spanEm.setAttribute("onclick", "delBoth(this)")
                        newNode.appendChild(spanEm);
                        newNode.setAttribute("id", oinpt.id + "d");
                        odWrp.insertBefore(newNode, oUpBtn);
                        newNode.style.backgroundImage = "url(" + this.result + ")";
                    }
                }
            }
    
    
             // 点击了预览图的X按钮后,删除对应的input file 和 该预览图。
            function delBoth(ths) {
                var oEm = ths;
                var strs = oEm.parentNode.getAttribute("id"); // 获取预览图的id
                var newStrs = strs.substring(0, strs.length - 1); // 删除末尾的字符,就是input file 的id
                odWrp.removeChild(oEm.parentNode);
                oform.removeChild(document.getElementById(newStrs));
            }
    
    
            // 删除空的input file的按钮,因为用户可能点击了上传文件,最后有可能取消了。那生成的input file却依旧在,所以需要这个
            function clearEnpt(oinpt) {
                if (oinpt.value == "") {
                    oform.removeChild(oinpt);
                }
            }
    
    
             // 每次点击addPic按钮时的操作
            oUpBtn.onclick = function() {
                var mInputs = oform.getElementsByTagName("input");
                
                 // 创建新的input file元素并添加
                var eleInpt = document.createElement("input");
                eleInpt.type = "file";
                eleInpt.id = "file" + i;
                eleInpt.name = "imgs" + i;
                // eleInpt.setAttribute("hidden", "hidden");
                eleInpt.setAttribute("onchange", "imgChange(this)");
                oform.appendChild(eleInpt);
                i++;
                
                 // 删除空的input file,除最后一个(因为它是我们上面才创建的,所以这里有坑.....)
                for (var j = 0; j < mInputs.length - 1; j++) {
                    clearEnpt(mInputs[j])
                }
    
                // 200毫秒后模拟input file 的点击效果
                setTimeout(function() {
                    eleInpt.click();
                }, 200);
    
            }
    

    基本备注已经添加完毕,感兴趣的小伙伴可以研究下!那个最后一个input 如果为空,目前有两种法子,要么最后点击“确认报名”时,再清除一遍空的input file。或者直接让后端,过滤掉空的。

    好了,到此,本文告一段落!感谢您的阅读!祝你身体健康,阖家幸福!

    相关文章

      网友评论

      • 冷凌凌花色:每次选择图片的时候,只能一张一张点击哇,然后选好一次图片,都出现一个input框在底下,还能点击它编辑,这个……:joy:
        kerush: @冷凌凌花色 嗯,可以这么理解
        冷凌凌花色:@kerush 哦哦,这样哇,然后,一次性只允许选择一张图片吗?
        kerush: @冷凌凌花色 其实input 本身是隐藏的,为了更好的表达,才显示出来
      • 099763990cf3:每上传一次就生成一次input??????
        kerush:@夏沫breathe :joy: 只是为了用户点删除时好操作
        099763990cf3:@kerush 我认为把input放在哪个加号上面触发不就好了吗,为什么要每次都生成呢
        kerush: @夏沫breathe 是啊,太多了?
      • springye:不错!谢谢分享!
        kerush: @springye 💪

      本文标题:类微信多图片上传

      本文链接:https://www.haomeiwen.com/subject/pznxhxtx.html