今天采用jq写了一个上传文件组件。支持进度异步上传

今天采用jq写了一个上传文件组件。支持进度异步上传,同时还支持上传后的图片移动,支持默认图片、支持单张图片(如修改头像),我后台保存处理代码是用vb.net的ashx来写的。这个只支持图片上传,需要文件上传的话请自已用代码修改。

 

以下是上传的效果图

UploadFile.ashx文件代码

<%@ WebHandler Language="VB" Class="UploadFile" %>
Public Class UploadFile : Implements IHttpHandler
  Public ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable
    Get
      Return False
    End Get
  End Property

  Public Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
    Dim File As HttpPostedFile = context.Request.Files("FileData"), Path As String = AppPath & "\UpFile\Temp\"
    With context.Response
      If File.FileName = "" Then .Write("文件无效") : .End()
      Dim FName As String() = File.FileName.Split(".")
      If FName.Length <> 2 Then .Write("文件名错误") : .End()
      If "gif|png|jpg|jpeg|".IndexOf(FName(1).ToLower & "|") < 0 Then .Write("文件格式错误") : .End()
      If IO.Directory.Exists(Path) = False Then IO.Directory.CreateDirectory(Path) '文件夹是否存在,不存在而创建
      Dim FileName As String = Format(Now, "yyMMdd") & "_" & NewGUID() & "." & FName(1)

      FileName = "1.jpg"
      '  File.SaveAs(Path & FileName)




      .Write("Yes|/UpFile/Temp/" & FileName) : .End()
    End With

  End Sub
End Class

UpLoadFile.js代码

/*二进制发送前进行转换,不然报错无法上传 1.2.2*/
if (!XMLHttpRequest.prototype.sendAsBinary) {
    XMLHttpRequest.prototype.sendAsBinary = function (datastr) {
        function byteValue(x) { return x.charCodeAt(0) & 0xff; }
        var ords = Array.prototype.map.call(datastr, byteValue); var ui8a = new Uint8Array(ords); this.send(ui8a.buffer);
    }
}
var MoveDiv, UpLoadInput //移动对象
var BeUpLoadFile = {
    Config: {
        multiple: 0,//单图上传
        id: '',
        DefaultValue: '',   //默认图片
        FileCount: 2,//总文件数量
        FileNum: 0,//当前文件数量
        Count: 0,   //待上传队列数
    },
    open: function (input, o, callback) {
        var that = this, Config = that.Config = $.extend(this.Config, o), FileDiv = $(input).parent();
        if (input.attr('multiple')) {
            Config.multiple = 1;
            Config.FileCount = input.data('count');
        }
        Config.DefaultValue = input.data('value');
        Config.id = UpLoadInput= input.attr('id')
        FileDiv.append("<input type='hidden' name='I" + Config.id + "' id='I" + Config.id + "' value='' />")
        input.attr('accept', 'image/*')
        input.bind('change', function () {
            if (this.files.length <= 0) { return }
            if (Config.multiple == 0) {  //单文件上传
                FileDiv.find('.Error').remove();
                $(this).before('<div class="Progress"><em>' + this.files[0].name + '</em></div>');
                that.uploadFile(this.files[0], FileDiv)
            } else {
                for (var n = 0; n < this.files.length; n++) {
                    that.AddItem(this.files[n], FileDiv)  //添加上传文件队列
                }
                that.UpFiles(FileDiv);
                if (Config.FileNum >= Config.FileCount) { FileDiv.hide(); }//达到上传限制数量
            }
        });
        var pics = Config.DefaultValue.split(",")
        for (var i = 0; i < pics.length; i++) {
            if (pics[i] != "") {
                var FItem
                if (Config.multiple == 0) {  //单文件上传
                    FItem = $(input).parent();
                } else {
                    FItem = $('<div class="Item" ><div class="Close"></div></div>')

                }
                FItem.append('<div class="Imgs"><img src="' + pics[i] + '" draggable="false" /></div>')
                FItem.data('status', 1)//上传完成标记
                FItem.data('src', pics[i]) //存储文件地址
                FItem.uploading = false;
                FItem.find('.Close').bind('click', function () {
                    that.RemoveItem($(this).parent())
                });
                FItem.data('Move', false)//是否正在移动
                FItem.data('Pos', { x: 0, y: 0 }) //默认位置
                FItem.data('Offset', { x: 0, y: 0 }) //默认位置
                FItem.bind('mousedown', that.MouseDown)//绑定移动事件
                FileDiv.before(FItem);
                Config.FileNum += 1;
            }
        }
        if (Config.multiple == 1) {
            $(document).bind('mousemove', that.MouseMove)
            $(document).bind('mouseup', that.MouseUp)
            $('#I' + this.Config.id).val(Config.DefaultValue);//存储默认地址
            if (Config.FileNum >= Config.FileCount) { FileDiv.hide(); }//达到上传限制数量
        }

    },
    //开始上传单个文件
    uploadFile: function (File, FileDiv) {
        var that = this, Config = this.Config, xhr = File.xhr = new XMLHttpRequest();
        File.uploading = true;//正在上传
        if (typeof FormData === 'function' || typeof FormData === 'object') {
            var formData = new FormData(); formData.append("FileData", File); xhr.open("post", "/Include/UploadFile.ashx", true);
            xhr.upload.addEventListener('progress', function (e) { that.progress(e, FileDiv) }, false);
            xhr.addEventListener('load', function (e) {
                File.uploading = false; //上传结束
                if (this.readyState == 4) {
                    if (this.status == 200) {
                        if (xhr.responseText.indexOf('Yes') >= 0) {
                            that.uploadComplete(e, xhr.responseText, FileDiv);
                        } else {
                            that.error(xhr.responseText, FileDiv);
                        }
                    } else if (this.status == 404) {
                        that.error("上传路径错误", FileDiv);
                    } else if (this.status == 403) {
                        that.error("无上传权限", FileDiv);
                    } else if (this.status == 500) {
                        that.error("文件太大", FileDiv);
                    } else {
                        that.error(this.status + "错误", FileDiv);
                    }
                }
            });
            xhr.send(formData);
        } else {
            var reader = new FileReader();
            reader.onload = function (e) {
                var boundary = '-------------------------' + (new Date).getTime(), dashes = '--', eol = '\r\n', binFile = '';
                binFile += dashes + boundary + eol;
                binFile += 'Content-Disposition: form-data; name="FileData"';
                if (File.name) { binFile += '; filename="' + File.name + '"' }
                binFile += eol;
                binFile += 'Content-Type: application/octet-stream' + eol + eol;
                binFile += e.target.result + eol;
                binFile += dashes + boundary + dashes + eol;
                xhr.upload.addEventListener('progress', function (e) { that.progress(e, FileDiv) }, false);
                xhr.addEventListener('load', function (e) {
                    File.uploading = false; //上传结束
                    if (this.status == 404) {
                        that.error("上传路径错误", FileDiv);
                    } else {
                        if (xhr.responseText.indexOf('Yes') >= 0) {
                            that.uploadComplete(e, xhr.responseText, FileDiv);
                        } else {
                            that.error(xhr.responseText, FileDiv);
                        }
                    }
                }, false);
                xhr.open("post", "/Include/UploadFile.ashx", true); xhr.setRequestHeader("Content-Type", "multipart/form-data; boundary=" + boundary); xhr.sendAsBinary(binFile);
            }
            reader.readAsBinaryString(File);
        }
        delete xhr;
    },
    //单个文件取消上传,发出拔出请求
    cancel: function (FileItem) {
        if (FileItem.uploading) {
            FileItem.uploading = false;
            FileItem.xhr.abort();
            delete FileItem.xhr;
        }
    },
    //单个文件上传错误
    error: function (msg, FileDiv) {
        FileDiv.find('.Progress').remove();
        FileDiv.append('<div class="Error">' + msg + '</div>')
    },
    //显示单个文件上传进度
    progress: function (e, FileDiv) {
        if (e.lengthComputable) {
            var percent = Math.round((e.loaded / e.total) * 100);
            FileDiv.find('.Progress em').html(percent + '%')
        }
    },
    //单个文件上传完成
    uploadComplete: function (e, responseText, FileDiv) {
        var that = this, Config = this.Config
        FileDiv.find('.Progress').remove();
        FileDiv.find('.Imgs').remove();
        FileDiv.append('<div class="Imgs"><img src="' + responseText.split("|")[1] + '"/></div>')
        FileDiv.data('status', 1)//上传完成标记
        FileDiv.data('src', responseText.split("|")[1]) //存储文件地址
        if (Config.multiple == 0) {//单文件上传
            FileDiv.find('#I' + Config.id).val(responseText.split("|")[1]);//更新存储地址
        } else {
            Config.Count -= 1;
            if (Config.Count <= 0) {
                that.ImgChange();//更新存储地址
            }

        }
    },
    //添加到队列
    AddItem: function (File, FileDiv) {
        var that = this;
        if (this.Config.FileNum >= this.Config.FileCount) { return }//超出限制数量
        File.Item = $('<div class="Item"><div class="Close"></div><div class="Progress"><em>' + File.name + '</em></div></div>')
        File.Item.data('File', File);
        File.Item.data('status', 0);//是否已经上传
        File.Item.find('.Close').bind('click', function () {
            that.RemoveItem(File.Item)
        });
        File.Item.data('Move', false)//是否正在移动
        File.Item.data('Pos', { x: 0, y: 0 }) //默认位置
        File.Item.data('Offset', { x: 0, y: 0 }) //默认位置

        File.Item.bind('mousedown', that.MouseDown)//绑定移动事件
        FileDiv.before(File.Item);
        this.Config.FileNum += 1; this.Config.Count += 1;
    },
    //移出队列
    RemoveItem: function (FileItem) {
        var Config = this.Config
        this.cancel(FileItem)
        if (FileItem.data('status') == 0) { Config.Count -= 1; }
        Config.FileNum -= 1;
        if (Config.FileNum < Config.FileCount) {
            FileItem.parent().find('.on').show();//未达上传限制数量
        }
        FileItem.remove();
        delete FileItem;
        this.ImgChange();
    },
    //批量依次上传
    UpFiles: function (FileDiv) {
        var that = this;
        FileDiv.parent().find('.Item').each(function () {
            var Item = $(this)
            if (Item.data('status') == '0') {
                that.uploadFile(Item.data('File'), Item)
            }
        });
    },
    //更新保存图片地址
    ImgChange: function () {
        var Imgs='';
        $('#' + UpLoadInput).parent().parent().find('.Item').each(function () {
            if ($(this).data('src')) {
                Imgs += $(this).data('src') + ',';
            }
        });
        if (Imgs != "") { Imgs = Imgs.substring(0, Imgs.length - 1) }
       $('#I' + UpLoadInput).val(Imgs);
    },

    //移动图像按下
    MouseDown: function (event) {
        var Div = MoveDiv = $(this), Pos = Div.data('Pos'), Offset = Div.data('Offset') //拖拽对象
        Div.data('Move', true); Div.css("z-index", 9999);
        Pos.x = Div.offset().left;//对象在屏幕位置
        Pos.y = Div.offset().top;
        Offset.x = event.pageX - Div.offset().left;//鼠标在对象上的偏位位置,还原需要负数
        Offset.y = event.pageY - Div.offset().top;
    },
    //移动图像位置
    MouseMove: function (event) {
        if (!MoveDiv) { return }
        if (!MoveDiv.data('Move')) { return }
        var Pos = MoveDiv.data('Pos'), Offset = MoveDiv.data('Offset')
        var NewPos = { x: 0, y: 0 }
        NewPos.x = event.pageX - Pos.x - Offset.x;//鼠标在对象上的偏位位置,还原需要负数
        NewPos.y = event.pageY - Pos.y - Offset.y;
        MoveDiv.css({ left: NewPos.x + 'px', top: NewPos.y + 'px' });
    },
    //移动图像松开
    MouseUp: function (event) {
        if (!MoveDiv) { return }
        MoveDiv.data('Move', false); MoveDiv.css("z-index", 0);
        var Pos = MoveDiv.data('Pos'), NewPos = { x: MoveDiv.offset().left - Pos.x, y: MoveDiv.offset().top - Pos.y }, Mode=0,end=0, w = MoveDiv.width() /2, h = MoveDiv.height() / 2
        if (NewPos.x < 0 && NewPos.y < 0) {//前上
            Mode = 1
        } else if (NewPos.x < 0 && NewPos.y > 0) {//前下
            Mode = 2
            end=0
        } else if (NewPos.x > 0 && NewPos.y < 0) { //后上
            Mode = 3
        } else if (NewPos.x > 0 && NewPos.y > 0) {//后下
            Mode = 4
            end=0
        } 
        NewPos = { x: MoveDiv.offset().left, y: MoveDiv.offset().top }
        MoveDiv.parent().find('.Item:not(.on)').each(function () {
            var ItemPos = { x: $(this).offset().left, y: $(this).offset().top }
            if (Mode == 1 || Mode == 3) {
                if (ItemPos.x > NewPos.x - w && ItemPos.y > NewPos.y - h) {
                    $(this).before(MoveDiv)
                    return false;
                }
            } else if (Mode == 2 || Mode == 4) {
                if (ItemPos.x > NewPos.x - w && ItemPos.y > NewPos.y - h) {
                    if (end > 0) {
                        $(this).after(MoveDiv)
                           return false;
                    }
                    end += 1
                }
            }
        });
        MoveDiv.css({ left: '0px', top: '0px' });//对齐处理
        BeUpLoadFile.ImgChange()
    }

};
$.fn.UpLoadFile = function () {
    BeUpLoadFile.open(this)
}













CSS代码,单张图片上传与多张上传是分开的。


/* 上传单张图片CSS */
.UpImg .Imgs img {
    max-width: 100%;
    max-height: 100%;
}

.UpImg .Error {
    width: 100%;
    z-index: 1;
    text-align: center;
    color: #e90908;
    position: absolute;
    bottom: 0px;
}

.UpImg .Progress {
    width: 100%;
    height: 100%;
    z-index: 1;
    background: url("/Images/loader.gif") no-repeat center #fff;
}

    .UpImg .Progress em {
        width: 100%;
        position: absolute;
        text-align: center;
        bottom: 0px;
        font-family: Arial;
    }
/* 上传多张图片CSS */
.UpImgs .Item {
    width: 100px;
    height: 100px;
    margin-right: 10px;
    margin-top: 10px;
    float: left;
    border: solid 1px #eee;
    position: relative;
    background:#efefef;
}
    .UpImgs .Item.on {
        border: solid 1px #efefef;
        background: url("/Images/UpImgView.gif") no-repeat center #f6f6f6;
    }

    .UpImgs .Item:hover {
        border: dashed 1px #f00;
    }

    .UpImgs .Item img {
        max-width: 100%;
        max-height: 100%;
    }

.UpImgs .Close {
    background: url("/Images/UPic_Del.png");
    width: 16px;
    height: 16px;
    position: absolute;
    z-index:2;
    right:0px;
    margin-top:-8px;
    margin-right:-8px;
    cursor:pointer;
}
.UpImgs .Error {
    width: 100%;
    z-index: 1;
    text-align: center;
    color: #f00;
    position: absolute;
    top: 50%;
    margin-top: -14px;
}
.UpImgs .Progress {
    width: 100%;
    height: 100%;
    z-index: 1;
    background: url("/Images/loader.gif") no-repeat center ;
}
    .UpImgs .Progress em {
        width: 100%;
        position: absolute;
        text-align: center;
        bottom: 0px;
        font-family: Arial;
    }

页面html代码

<!doctype html>

<html>
<head>
  <meta charset="utf-8">
  <meta http-equiv="Content-Type" content="text/html;charset=utf-8">
  <title>JS上传方件组件</title>
  <meta name="description" content="">
  <meta name="keywords" content="">
  <meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1" />
  <meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">
  <link href="/Global.css" rel="stylesheet" type="text/css" media="all" />
  <script src="/Include/jquery.js" charset="utf-8" type="text/javascript"></script>
  <script src="/Include/UpLoadFile.js" charset="utf-8" type="text/javascript"></script>


</head>
<body>
  <div class="PageTitle">
    上传文件
  </div>



  <div class=" UpImgs" style="margin-top:20px;"> 
      <div class="Item on">
        <input id="Picture" name="Picture" type="file" multiple="multiple"  data-count="100" data-value="/UpFile/Temp/1.jpg,/UpFile/Temp/2.jpg,/UpFile/Temp/3.jpg,/UpFile/Temp/4.jpg,/UpFile/Temp/5.jpg,/UpFile/Temp/6.jpg,/UpFile/Temp/7.jpg,/UpFile/Temp/8.jpg,/UpFile/Temp/9.jpg,/UpFile/Temp/10.jpg,/UpFile/Temp/11.jpg,/UpFile/Temp/12.jpg,/UpFile/Temp/13.jpg,/UpFile/Temp/14.jpg,/UpFile/Temp/15.jpg,/UpFile/Temp/16.jpg"  />
       </div>


  </div>







  <script type="text/javascript">
    // capture='camera'


    $("#Picture").UpLoadFile()
  </script>
</body>
</html>

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值