多文件拖拽上传以及利用Jquery替代HTML5上传控件

本文探讨了两种文件上传方式:一是文件拖拽上传,模拟QQ邮箱的拖拽体验;二是利用Jquery替换HTML5上传控件,展示进度条和返回结果。详细介绍了前端JS代码实现,包括FormData的使用,以及文件拖拽和上传的各个步骤。同时,提到了JqueryUploadify控件的使用方法,以增强文件上传的交互体验。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近一直在研究文件上传的各种方法以及使用其他控件去重构HTML5自带的上传控件,这一篇将会总结这段时间研究的文件上传的两种方式,并对这一方面告一段落。

本文将分为两部分介绍并解释文件上传的原理和实现过程,第一篇为多文件拖拽上传,类似于QQ邮箱文件拖拽一样;第二篇为使用Jquery代替HTML5上传控件,比较华丽的为每一个文件显示进度条和显示返回结果。


第一篇——拖拽

文件拖拽即把一个或多个文件从电脑桌面选中,拖移至我们的页面上传区,并记录下每一个文件的信息,反馈给后台。

首先是给出一个前台页面,一个form表单,包含它的各种属性,特别是(enctype=”multipart/form-data”) 这个属性是设置表单的MIME编码。默认情况,这个编码格式是application/x-www-form-urlencoded,不能用于文件上传;只有使用了multipart/form-data,form里面的input的值以2进制的方式传到后台,保留完整的传递文件数据,进行后台文件处理的操作.

<form id="upload" action="Handler1.ashx" method="post" enctype="multipart/form-data">
 <div class="example ">
      <div id="drop_zone">将文件拖拽到这里</div>
      <div id="output_area"></div>
      <input type="button" value="拖拽上传" onclick="Upload();" />
  </div>
</form>

接下来会逐步展示并一步步解释完整的JS代码,请准备好瓜子和饮料:

初始化的四个基本参数,不得不说一下强大的FormData,它是XMLHttpRequest里面的一个接口,我们利用FormData对象,可以把所有表单元素的name与value组成一个queryString,提交到后台。之后使用XMLHttpRequest的 send( ) 方法来异步提交表单,与普通的ajax相比,使用FormData的最大优点就是可以异步上传二进制文件。

var fd = new FormData();
var FileIndex = 0;
var output = document.getElementById('output_area');
var dropZone = document.getElementById('drop_zone');

接下来我们就需要构造文件拖拽的过程:1.文件进入,2.文件离开,3. 文件拖拽完成效果,4.文件拖拽到页面后处理方式。
这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

//首先对页面事件做一个判断处理,如果页面中存在并满足下列if条件就触发事件方法。
if ((('draggable' in dropZone) && ('ondragenter' in dropZone)
            && ('ondragleave' in dropZone) && ('ondragover' in dropZone)
            && window.File && window.FileList && window.FileReader)) {

    //文件进入事件
    function handleFileDragEnter(e) {
         //不再派发事件
         e.stopPropagation();
         //取消事件的默认动作
         e.preventDefault();
         //为当前元素添加CSS样式(这里使用到的样式均会在下面展示出来)
         this.classList.add('hovering');
    }

    //文件离开事件
    function handleFileDragLeave(e) {
         e.stopPropagation();
         e.preventDefault();
         //为当前元素移除CSS样式
         this.classList.remove('hovering');
    }

    //文件拖拽完成效果
    function handleFileDragOver(e) {
         e.stopPropagation();
         e.preventDefault();
         //把拖动的元素复制到放置目标(注1会给出dropEffect详细属性)。
         e.dataTransfer.dropEffect = 'copy';
    }

    //文件拖拽到页面后处理方式
    function handleFileDrop(e) {
         e.stopPropagation();
         e.preventDefault();
         //为当前元素移除CSS样式
         this.classList.remove('hovering');

        //target 事件属性可返回事件的目标节点(触发该事件的节点),如生成事件的元素、文档或窗口。
         var files = e.target.files || e.dataTransfer.files;
         for (var i = 0, f; f = files[i]; i++) {
             FileIndex++;
             //FormData提供的append方法把数据写入到fd中
             fd.append("FileData_" + FileIndex, files[i]);
         }

         var files = e.dataTransfer.files;
         //根据files[]获得的数据,在前台页面写出上传的文件基本信息
         var outputStr = [];
         for (var i = 0, f; f = files[i]; i++) {
             var lastModified = f.lastModifiedDate;
             var lastModifiedStr = lastModified ? lastModified.toLocaleDateString() + ' ' + lastModified.toLocaleTimeString()
                                                : 'n/a';
             outputStr += '<li><strong>' + f.name + '</strong></li>';
         }
         output.innerHTML = '<ul>' + outputStr + '</ul>';
    }

//为四种方法生成addEventListener事件监听器,addEventListener有三个参数:第一个参数表示事件名称;第二个参数表示要接收事件处理的函数;第三个参数为 useCapture(一般来说为false,true会更改响应顺序),
dropZone.addEventListener('dragenter', handleFileDragEnter, false);
dropZone.addEventListener('dragleave', handleFileDragLeave, false);
dropZone.addEventListener('dragover', handleFileDragOver, false);
dropZone.addEventListener('drop', handleFileDrop, false);
}

文件响应事件之后,就要为数据传递到后台做准备了:

function Upload() {
    //创建XMLHttpRequest方法
    var xhr = new XMLHttpRequest();
    //添加事件监听器(同dropZone监听方法)
    xhr.upload.addEventListener("progress", uploadProgress, false);
    xhr.addEventListener("load", uploadComplete, false);
    xhr.addEventListener("error", uploadFailed, false);
    xhr.addEventListener("abort", uploadCanceled, false);
    //使用open()和send()建立并发送响应事件
    xhr.open("POST", "Handler1.ashx");
    xhr.send(fd);
}

//显示进度条
function uploadProgress(evt) {
    if (evt.lengthComputable) {
        var percentComplete = Math.round(evt.loaded * 100 / evt.total);
        document.getElementById('progressNumber').style.width = percentComplete + '%';
    }
    else {
        document.getElementById('progressNumber').innerHTML = 'unable to compute';
    }
}

//抛出反馈成功结果
function uploadComplete(evt) {
    alert(evt.target.responseText);
}
//抛出异常提示
function uploadFailed(evt) {
    alert("上传文件异常.");
}
//抛出取消提示
function uploadCanceled(evt) {
    alert("取消.");
}

后台程序:接受前台数据并作出处理

if (context.Request.Files != null)
{
    //服务器端文件保存路径  
    string uploadPath = HttpContext.Current.Server.MapPath(@context.Request["folder"]) + "\\file\\";
    //循环对每一个文件作出处理
    foreach (string fileDate in context.Request.Files.AllKeys)
    {
        HttpPostedFile f = context.Request.Files[fileDate];
        if (f != null && f.FileName != "")
        {
            string title = context.Request.Form["title"];
            f.SaveAs(uploadPath + f.FileName);//保存文件  
            context.Response.Write("上传成功");
        }
    }
}

第二篇——控件

这一篇将会使用Jquery替代HTML5的上传控件,并增加文件信息展示和上传进度条。

首先我们需要下载JqueryUploadify这一个控件包(注2提供下载链接地址),里面包含以下几个引用:

<script src="/js/jquery-1.3.2.min.js" type="text/javascript"></script>  
<script src="/js/jquery.uploadify.v2.1.0.js" type="text/javascript"></script>  
<script src="/js/jquery.uploadify.v2.1.0.min.js" type="text/javascript"></script>  
<script src="/js/swfobject.js" type="text/javascript"></script>  
<link href="/css/uploadify.css" rel="stylesheet" type="text/css" /> 

在前台页面中写入form表单和相应的按钮

<form id="form1" runat="server">  
    <div id="fileQueue">         
    </div>  
        <div>  
            <p>  
                <input type="file" name="uploadify" id="uploadify"/>  
                <input id="Button1" type="button" value="上传" onclick="javascript: $('#uploadify').uploadifyUpload()" />  
                <input id="Button2" type="button" value="取消" onclick="javascript: $('#uploadify').uploadifyClearQueue()" /> 
            </p>  
        </div>  
</form>  

然后写一下uploadify的JS:

<script type="text/javascript">  
       $(document).ready(function () {  

           $("#uploadify").uploadify({  
               'uploader': 'image/uploadify.swf',  //uploadify.swf文件的相对路径,该swf文件是一个带有文字BROWSE的按钮,点击后淡出打开文件对话框                
               'script': 'Handler1.ashx',//    script :  后台处理程序的相对路径  
               'cancelImg': 'image/cancel.png',  
               'buttenText': '请选择文件',//浏览按钮的文本,默认值:BROWSE。  
               'sizeLimit':999999999,//文件大小显示  
               'floder': 'Uploader',//上传文件存放的目录  
               'queueID': 'fileQueue',//文件队列的ID,该ID与存放文件队列的div的ID一致  
               'queueSizeLimit': 120,//上传文件个数限制  
               'progressData': 'speed',//上传速度显示  
               'auto': false,//是否自动上传  
               'multi': true,//是否多文件上传  
               //'onSelect': function (e, queueId, fileObj) {  
               //    alert("唯一标识:" + queueId + "\r\n" +  
               //  "文件名:" + fileObj.name + "\r\n" +  
               //  "文件大小:" + fileObj.size + "\r\n" +  
               //  "创建时间:" + fileObj.creationDate + "\r\n" +  
               //  "最后修改时间:" + fileObj.modificationDate + "\r\n" +  
               //  "文件类型:" + fileObj.type);  

               //    }, 
               'onQueueComplete': function (queueData) {  
                   alert("文件上传成功!");                    
                   return;  
               }  

           });  
       });  
</script>

最后后台程序和我们第一篇使用的后台处理是同一程序,下面是图片展示区:

这里写图片描述

这里写图片描述

这里写图片描述

如果报错或者超出文件上传限制将会用下面的方式提示用户

这里写图片描述


CSS样式区:

<style>
    #drop_zone {
      border: 2px dashed #BBB;
      padding: 25px 5px;
      text-align: center;
      font-size: 20pt;
      color: #BBB;
      border-radius: 5px;
    }
    #drop_zone.hovering {
      -webkit-box-shadow: inset 0px 0px 50px #BBB;
      -moz-box-shadow: inset 0px 0px 50px #BBB;
      -o-box-shadow: inset 0px 0px 50px #BBB;
      box-shadow: inset 0px 0px 50px #BBB;
    }
    .example {
      margin: 40px 25px;
      padding: 10px;
      border: 1px solid #BBB;
    }
    #description:first-line {
      margin-left: 42px;
    }
    #output_area {
      text-align: left;
    }
    #output_area li {
      margin: 10px 0;
    }
  </style>

注1:运用dataTransfer对象,不仅仅能传输数据,还能通过dataTransfer对象确定被拖拽的元素以及作为放置目标的元素能够接收什么操作。

其中,通过dropEffect属性可以知道被拖动的元素能够执行哪种行为。这个属性的四个值如下:

none:不能把拖动的元素放在这里。这是除了文本框之外所有元素默认的值。

move:把拖动的元素移动到放置目标。

copy:把拖动的元素复制到放置目标。

link:放置目标会打开拖动的元素(但拖动的元素必须是个链接,有URL地址)。

把元素拖动到放置目标上的时候,以上每一个值都会导致光标显示为不同的符号。

注2:http://www.uploadify.com/documentation/ 官方控件包下载地址

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值