H5单张、多张图片上传

前言

今天咱们聊一聊图片上传,单张Or多张 ,现在,各大图片上传插件数不胜数,例如:Jquery的 verupload.js,jQuery File Upload、Uploadify、jQuery.filter等等。But。上面说到的这些插件,今天咱们不谈,咱们来看一看使用HTML5中的FileReader 如何实现 图片的单张及多张预览、删除、上传等功能。css

先看下实现后的效果以下:html

 

实现

前端部分

这块是用户点击按钮 其中咱们最重要的一句话是input type=file 和给了一个multiple属性,能够知足多张图片上传前端

<div class="form-group form-row">
        <label class="col-sm-2 control-label uText">俱乐部相册</label><div class="row">
                        <div class="col-xs-10 col-sm-8 mTop5">
                            <label title="上传俱乐部相册" for="ClubImagesUpload" id="btnClubImg" class="col-sm-2">
                                
                                <input type="file" accept="image/*" name="ClubImagesUpload" id="ClubImagesUpload" class="hide" multiple="multiple">
                           
                                <img src="/Images/registerNewSite/btn_addimg.png" class="addImg"/>
                            </label>
                        </div>
                    </div></div>

下面这块区域是用于图片预览的web

<div class="form-group form-row" id="preViewMore"><div class="row">
      <div class="col-xs-9">
         <div id="clubInputImagePreview" class="col-sm-9 img-preview img-preview-sm"></div>
       </div>
  </div></div>

 

样式部分

什么?连样式你都要看,还有没有人性(苦笑脸)数据库

Js部分

首先咱们分析下上面的html,咱们用一个label把input和一个img标签包起来了,咱们但愿点击效果图那个+号图片,就能弹出选择相片的对话框,因此,咱们须要先给label来一个点击事件:后端

$("#btnClubImg").click(function() {
    //TODO Something
});

接着咱们再看,由于咱们是要获取上传的文件,而咱们的文件主要是在input上,因此,咱们先将input标签获取到:浏览器

$("#btnClubImg").click(function() {
      var $input = $("#ClubImagesUpload");
     console.log($input);//打印当前元素
});

咱们将当前input元素标签打印出来看看是个什么东东app

咱们展开第一项会发现files里面length长度是0异步

好,咱们继续分析,由于咱们想要能当input框改变的时候,说简单点 就是有选择到文件的时候,咱们能获取到当前选择的文件,这个和获取input框文字输入是同样的道理,因此,通过分析,咱们知道须要给input标签加一个change事件:ide

 $("#btnClubImg").click(function() {
      var $input = $("#ClubImagesUpload");
      console.log($input);
      $input.on("change", function () {
         console.log(this);//打印改变后的当前元素
  });
});            

让咱们来瞄一眼,获取到改变后的input元素里面有些啥东东:

这里很清楚得能够看到,咱们获取到了选择的图片,包括有最后修改事件,图片名称,大小以及图片类型(有了文件类型,咱们就能够判断当前用户选择的是不是图片不是吗(斜眼笑))

一样,这是单个文件的, 若是是多个文件,就会有多个file

接着往下看,经过打印输出咱们能够看到,咱们再input 标签的files元素上已经拿到了咱们想要的文件信息,咱们只须要获取它们就好了:

 var files = this.files;
 var length = files.length;

这样,咱们就能够获取到全部文件,以及文件的个数,那这里问题来了,咱们若是是选择多个文件,若是将其依次输出并展现到页面上呢?

看到上面标注的四个字,脑壳中有没有闪现出两个字呢?循环

 $.each(files, function (key, value) {
        //TOTO Something
  });

经过将上面获得的files 循环,咱们能够依次获得每一个文件的信息。这样,你就不只能够将其依次输出,若是你愿意,你还能够将其送上天~

var fileReader = new FileReader();//实例化一个FileReader对象
var file_ = files[key];//获取当前文件
if (/^image\/\w+$/.test(file_.type)) {//将当前文件进行正则匹配,看是不是选择的图片
      fileReader.onload = function() {//当读取操做完成时调用
    
       }         
}               

有必要延伸下FileReader的知识点:

FileReader主要用于将文件内容读入内存,经过一系列异步接口,能够在主线程中访问本地文件。

使用FileReader对象,web应用程序能够异步的读取存储在用户计算机上的文件(或者原始数据缓冲)内容,可使用File对象或者Blob对象来指定所要处理的文件或数据。

回到主题,咱们已经可以获得文件而且获得返回,因此此时,咱们只须要展现返回的结果就好了

 $("#clubInputImagePreview").css("background-image", "url(" + this.result + ")");

咱们将其this.result打印出来看看是个什么东东:

不言而喻,是将图片转换成了Base64的数据格式。最后,咱们调用 readAsDataURL 读取文件内容,将其用data:url字符串表示出来

fileReader.readAsDataURL(value);

这样,你就能够获得一个简易的图片上传的Demo了,可是并非最终的,由于你还须要加不少业务进去。好比:获得一张预览图片后,当前标签会被占用,若是下次循环进来,直接使用原标签,确定会将以前的图片替换,那这确定不是咱们想要的效果,

咱们但愿是能依次展现,而不是替换展现。因此,咱们还须要作一些处理:

 $("#clubInputImagePreview").css("background-image", "url(" + this.result + ")");

//使用apend再当前元素下追加一个子节点
 $("#clubInputImagePreview") .append("<img src='/Images/registerNewSite/btn_r_del.png' class='clubsImage'  id='ImgRemove' />");

//使用after 向当前兄弟节点 追加一个同级节点                                       
$("#clubInputImagePreview").after( "<div id='clubInputImagePreview1' class='col-sm-9 img-preview img-preview-sm delImg' ></div>");

而后咱们追加的删除图片,也须要给其点击事件,让咱们的当前预览区域消失:

$("#ImgRemove").click(function () {
          $(this).parent().remove();
});

最后,你会发现结果还不是咱们想要的,那是由于 当前ID还在,因此没法进行下一步操做,而咱们只须要将当前元素的Id Remove掉,而后新增一个同ID的元素,这样浏览器就会认为这是一个新的元素:

 $input.removeAttr("id");
 var newInput ='<input type="file" accept="image/*" name="ClubImagesUpload" id="ClubImagesUpload" class="hide" multiple="multiple">';
 $(this).append($(newInput));

最后完整JS代码以下:

  var intP = 0;
        $("#btnClubImg").click(function() {
            var $input = $("#ClubImagesUpload");
//            console.log($input);
            $input.on("change",
                function () {
//                    console.log(this);
                    var files = this.files;
                    var length = files.length;
                    if (intP > 8) {
                        layer.msg('图片不能再多了~', {});
                        return;
                    }

                    $.each(files,
                        function (key, value) {
                            var fileReader = new FileReader();
                            var file_ = files[key];
                            if (/^image\/\w+$/.test(file_.type)) {
                                fileReader.onload = function() {
                                    if (intP > 8) {
                                        layer.msg('图片不能再多了~', {});
                                        return;
                                    }
                                    if (key == 0 && intP == 0) {
                                        console.log(this.result);
                                        $("#clubInputImagePreview").css("background-image", "url(" + this.result + ")");

                                        $("#clubInputImagePreview")
                                            .append(
                                            "<img src='/Images/registerNewSite/btn_r_del.png' class='clubsImage'  id='ImgRemove' />");
                                        
                                        $("#clubInputImagePreview").after(
                                            "<div id='clubInputImagePreview1' class='col-sm-9 img-preview img-preview-sm delImg'></div>");
                                    } else {
                                        $("#clubInputImagePreview" + parseInt(intP) + "").css("background-image",
                                            "url(" + this.result + ")");

                                        $("#clubInputImagePreview" + parseInt(intP) + "").append(
                                            "<img src='/Images/registerNewSite/btn_r_del.png' class='clubsImage'  id='ImgRemove" +
                                            parseInt(parseInt(1) + parseInt(intP)) +"' />");

                                        $("#clubInputImagePreview" + parseInt(intP) + "").after(
                                            "<div id='clubInputImagePreview" +
                                            parseInt(parseInt(1) + parseInt(intP)) +
                                            "'class='col-sm-9 img-preview img-preview-sm delImg' ></div>");
                                    }
                                    if (key == 0 && intP == 0) {
                                        $("#ImgRemove").click(function () {
                                            $(this).parent().remove();
                                        });
                                    } else {
                                        $("#ImgRemove" + parseInt(parseInt(1) + parseInt(intP)) + "").click(function () {
                                            $(this).parent().remove();
                                        });
                                    }

                                    intP += parseInt(1);
                                };
                                fileReader.readAsDataURL(value);
                            } else {
                                layer.msg("格式错误<br/>请选择一个图片文件");
                            }
                        });
                

                });


            $input.removeAttr("id");
            var newInput =
                '<input type="file" accept="image/*" name="ClubImagesUpload" id="ClubImagesUpload" class="hide" multiple="multiple">';

            $(this).append($(newInput));

        });

 

下一篇,将讲述 如何将前端获得的多个File ,存入进数据库,后端是.NET Core,敬请期待吧~