stoneniqiu 阅读(213) 评论(0)

     图片上传的插件很多,但正真很难十分切合我们的需求。我这里讲的是用一个flie元素上传4张照片的一个Demo。用到了bootstrap和form.js。最终效果图如下:

     

    有些人可能看着熟悉,这个原型是花田网站中上传图片插件的样式。

    准备的js如下:

  <script src="../../Scripts/jquery-ui-1.9.2.custom.min.js"></script>
    <script src="../../Scripts/jquery-1.8.3.js"></script>
    <link href="../../Content/bootstrap/css/bootstrap.min.css" rel="stylesheet" />
    <script src="../../Content/bootstrap/js/bootstrap.min.js"></script>
  <script src="../../Content/JS/form.js"></script>
View Code

   实现的大体思路:

        一般的file文件需要选择浏览,选中图片,再点确定才能提交。 但插件提供的一般都是直接选择照片就可以预览了。其实是让file文件自动提交了存入临时文件夹,形成预览图片。而提交动作当然是要有form元素来完成。因为上传的动作都是一样的,所以我想用一个file就行了。file自动提交后台只要符合格式和大小就会先存入临时文件夹,用户如果要删除就删除临时文件夹中的图片。而提交是简单的事情了,只需要把之前的图片地址存入数据库,再把临时文件中的文件move到规范的文件夹中就可以。 以上就是整个思路。 代码如下:

   html如下:最后面有一个隐藏的form,才是真正上传幕后。

  <div id="imgupload" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
        <div class="modal-header">
            <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
            <h4>上传图片</h4>  
        </div>
        <div class="modal-body">
            <div class="uploadbox" data-count="0" style="display: inline;">
                <span class="closespan" title="删除照片">&times;</span>
                <div class="imgcontainer">
                    <div class="add">+</div>
                    <div class="stt">点击上传</div>
                </div>
                <span class="infospan">
                    <img src='../../Content/Photos/loading.gif' />正在上传...</span>
            </div> 
            <div class="uploadbox" data-count="0"  >
                <span class="closespan" title="删除照片">&times;</span>
                <div class="imgcontainer">
                    <div class="add">+</div>
                    <div class="stt">点击上传</div>
                </div>
                <span class="infospan">上传成功2</span>
            </div> 
            <div class="uploadbox"data-count="0" >
                <span class="closespan" title="删除照片">&times;</span>
                <div class="imgcontainer">
                    <div class="add">+</div>
                    <div class="stt">点击上传</div>
                </div>
                <span class="infospan">上传成功3</span>
            </div> 
            <div class="uploadbox"data-count="0"  >
                <span class="closespan" title="删除照片">&times;</span>
                <div class="imgcontainer">
                    <div class="add">+</div>
                    <div class="stt">点击上传</div>
                </div>
                <span class="infospan">上传成功4</span>
            </div> 
            <div class="inputdiv"><input type="text" disabled="disabled" id="Remark" name="Remark" placeholder="补充说明下~"/></div>
        </div>
            <div class="modal-footer">
             上传大小在8k-10M之间 <span class="imguploadmessage"></span>
              <button class="btn btn-success "  disabled="disabled"   id="imgsubmit">发布</button>
              <form action="/User/UpLoadPhoto" method="POST" enctype="multipart/form-data" name="ImgForm" id="ImgForm">
              <input type="file" name="file" id="imgFlie"  required="required" />
              <input type="submit" name="subt" value="上传图片" />
              </form>
            </div>
   
    </div>
View Code

 这里还有部分逻辑

 1.初始的时候显示一个上传块,上传完成一个图片后才会显示下一个块。切这个块始终在最后面。2.没有上传图片的时候 描述框和发布按钮都要是disabled状态。3上传完成之后的照片不允许再次点击上传,要再次上传先删掉原来的照片。

 

  //图片上传-------------------------------------imgupload---------------------

    var imgbox = {};//用来获取当前点击的块  因为块的顺序是变动的,所以用each函数是不准确的。
    var childs = $(".imgcontainer:eq(0)").html();
    $(".uploadbox").click(function () {
        var tag = $(this).attr("data-count");// 我增加了一个data-count属性来判断是否已经存在照片,给div加disabled貌似没有用。
        if (tag == "1") return false;//表示上传完成 
        $("#imgFlie").click(); //点击上传块 其实是点击file元素,触发用户选择图片
        imgbox = $(this);
        var stm1 = setInterval(function () { //用timer来判断用户是否选择了图片 如果选择了就自动提交。 如果你有更好的办法,欢迎指出。
            var imgstr = $("#imgFlie").val();
            if (imgstr != "") {
                clearInterval(stm1);
                $("#ImgForm input[type='submit']").click();
            }
        }, 500);
        return false;
    });

    // 取消照片
    $(".closespan").click(function (e) {
        e.stopPropagation();
        var sum = $(".uploadbox img").length;
        // 保证有一个框可以让用户再次选择 需要显示childs 设置data-count属性 必要的再隐藏
        var imgsrc = $(this).next().find("img").attr("src");
        $(this).next().html("").append(childs);
        // 隐藏关闭和成功提示
        $(this).hide();
        $(this).siblings(".infospan").hide();
        $(this).parent().attr("data-count", 0).insertBefore($(".inputdiv"));//取消之后,还原data-count属性 然后插入到上传块队列的最后 也就是描述框前面

        if (sum < 4) {//说明此时是有一个在准备状态,这个可以直接做删除处理 
            // 设置data-count 并隐藏父级
            $(this).parent().hide();
            //需要移位 保证准备状态的总是在最后一个  
        }
        // 清除session 减少一个字符串
        if (imgsrc != undefined) {
            $.post("/User/DeleteImg", { str: imgsrc }, function () {//清楚src 和图片
            });
        }
        if (sum == 1) {
            $('#Remark,#imgsubmit').attr("disabled", "disabled"); //表示这个时候还没有图片,禁止提交键和描述框
        }

    });

 

 //----------上传图片---------------------------------------------
    $("#imgsubmit").click(function () {
        var imgcontent = $.trim($("#Remark").val());
        $.post("/User/SaveImgs", { content: imgcontent }, function (data) {
            if (data == 1) {//上传成功之后 还原到最初状态的处理
                //清除content
                $(".imgcontainer").html(childs);
                //隐藏进度条和关闭键
                $(".closespan,.infospan").hide();
                $(".imguploadmessage").html("上传成功!");
                //禁止输入框和提交按钮
                $('#Remark,#imgsubmit').attr("disabled", "disabled");
                //去掉data-count 属性 显示第一个;
                $(".uploadbox").attr("data-count", 0).hide().eq(0).show();
                //清空
                $("#Remark").val("");
                var stt = setTimeout(function () {
                    $("#imgupload").modal('hide');
                    $(".imguploadmessage").html("");
                    clearTimeout(stt);
                }, 1000);
            }
        });
    });

    $('#ImgForm').ajaxForm({//form插件来异步提交
        beforeSend: function () {
            imgbox.find(".infospan").show();//显示正在上传... 
        },
        success: function (data) {
            $("#imgFlie").val("");//
            imgbox.find(".imgcontainer").html(data);//.hide()
            var img = imgbox.find(".imgcontainer").find("img").attr("src");
            if (img != undefined) {//返回的没有图片,表示上传的图片有问题。 
                //解禁
                $('#Remark').removeAttr("disabled");
                $('#imgsubmit').removeAttr("disabled");
                imgbox.find(".infospan,.closespan").show();
                imgbox.find(".infospan").html("上传成功!");
                //显示下一个
                //imgbox.next().show();
                $(".uploadbox:hidden").eq(0).show();

                imgbox.attr("data-count", "1");
            } else {
                imgbox.find(".infospan,.closespan").hide();// 结果栏和关闭继续隐藏 中间会显示错误信息。
            }
            // alert(img);
        }, complete: function (xhr) {
            $("#imgFlie").val("");
        }
    });

 后台的处理:

  一共是五个函数:来处理 上传,删除图片,保存图片,检查图片和获取扩展名。 在这里我用了session来存储url,临时文件的地址和存入数据库的地址是不一样的。

 每张图片也重新命名了。

 /// <summary>
        /// 删除预览中的照片
        /// </summary>
        /// <param name="str">这个str 已经是处理过的,不是之前上传的图片名称</param>
        public void DeleteImg(string str)
        {
            //删除地址 删除文件
            var list = Session["Imgscr"] as List<string>;
            if (list == null) return;
            var index = list.IndexOf(str);
            var slist = Session["ImgServerscr"] as List<string>;
            if (slist != null && index != -1)
            {
                var imgone = slist[index];
                if (imgone != null)
                {
                    var img = new FileInfo(imgone);
                    if (img.Exists) img.Delete();
                }
            }
            list.Remove(str);
        }

 private string CheckImg(HttpPostedFileBase file)
        {
            if (file == null) return "图片不能空!";
            if (file.ContentLength / 1024 > 8000)
            {
                return "图片太大";
            }
            if (file.ContentLength / 1024 < 10)
            {
                return "图片太小!";
            }
            var image = GetExtensionName(file.FileName).ToLower();
            if (image != ".bmp" && image != ".png" && image != ".gif" && image != ".jpg" && image != ".jpeg")// 这里你自己加入其他图片格式,最好全部转化为大写再判断,我就偷懒了
            {
                return "格式不对";
            }

            var scrtemp = Path.Combine("../../Content/TempFile/", file.FileName);//图片展示的地址
            var list = Session["Imgscr"] as List<string>;
            if (list != null && list.Find(n => n == scrtemp) != null)
            {
                return "同样的照片已经存在!";
            }

            return "ok";
        }

 public JsonResult SaveImgs(string content)
        {
            var uid = CheckValid();//获取id
            if (_uName == null) _uName = GetUserNameById(uid);

            string path = Path.Combine(HttpContext.Server.MapPath("../Content/UploadFiles/"), _uName, "Photos", "ImgBox");
            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }
            var list = Session["Imgscr"] as List<string>;
            var finallist = new List<string>();
            if (list == null) return Json(0);
            foreach (var str in list)
            {
                var scrtemp1 = Server.MapPath(str.Substring(3, str.Length - 3));//去掉第一个../
                var img = new FileInfo(scrtemp1);
                if (img.Exists)
                {
                    var image = GetExtensionName(img.Name);
                    //处理照片名称
                    var imgname = string.Format("{0:yyyMMdd}", DateTime.Now).Replace("/", "") + DateTime.Now.Ticks.ToString(CultureInfo.InvariantCulture).Substring(7, 11) + image;
                    var scrdestination = Path.Combine(HttpContext.Server.MapPath("../Content/UploadFiles/"), _uName, "Photos", "ImgBox", imgname);
                 
                    var scrshow = Path.Combine(("../../Content/UploadFiles/"), _uName, "Photos", "ImgBox", imgname);
                    finallist.Add(scrshow);
                    //移动照片
                    img.MoveTo(scrdestination);
                    //存入imgbox
                    var box = new Iamgbox
                    {
                        ActionTime = DateTime.Now,
                        BoxName = _uName,
                        ImgUrl = scrshow,
                        IsValid = true, //默认是正规合适的图片 不合适在检举
                        PraiseCount = 0,
                        Remark = content,
                        UserId = uid,
                        VisitCount = 0,
                    };
                    LoveDb.Add(box);
                };
            }
            if (finallist.Count() != 0)
            {
                var sbstr = new StringBuilder("<br/><div class='imgtigger'>");
                foreach (var str in finallist)
                {
                    sbstr.Append("<img src='" + str + "' />");
                }
                sbstr.Append("</div>");
                var state = new State
                {
                    ActionTime = DateTime.Now,
                    Content = (content == "" ? string.Format("刚刚上传了{0}张照片:", finallist.Count) : content)+sbstr,
                    PraiseCount = 0,
                    StateType = StateType.Image.ToString(),
                    UserId = uid
                };
                LoveDb.Add(state);
                Session.Remove("Imgscr");
                Session.Remove("ImgServerscr");
            }
              

            return Json(1);
        }
  public string GetExtensionName(string fileName)
        {
            if (fileName.LastIndexOf("\\", StringComparison.Ordinal) > -1)//在不同浏览器下,filename有时候指的是文件名,有时候指的是全路径,所有这里要要统一。
            {
                fileName = fileName.Substring(fileName.LastIndexOf("\\", StringComparison.Ordinal) + 1);//IndexOf 有时候会受到特殊字符的影响而判断错误。加上这个就纠正了。
            }
            return Path.GetExtension(fileName.ToLower());
        }
View Code

这样 整个图片上传就完成了。希望对你有帮助!