zoukankan      html  css  js  c++  java
  • File控件杂谈

      我们通常使用<input type='file'/>来实现网页中文件上传功能,用户可以通过点击file控件选择本地文件,当我们提交包含该控件的表单时,浏览器会向服务器发送用户选中的文件。

      看上面的描述,file控件貌似挺强大的,事实上也是这样的。但实际开发中我们也可以挑出file控件的诸多问题:

      1、我们可以通过value属性获取用户选择的文件的名称,但出于安全因素,该属性只读,所以也就无法指定默认值。

      2、最让我们诟病的是,file控件在不同浏览器上长相迥异。这让我们开发者情何以堪?而且“选择文件”、“浏览…”等字样均无法修改。更可恶的是IE9file控件类似于输入框的位置需要双击才能触发文件选择。这样的视觉效果与交互体验着实让我们无法接受。

      so,目前普遍的解决方案是这样的:

      在file控件外面包裹一层容器,并设置其尺寸,通过定位将file控件右侧区域(因为IE9file控件左侧区域单击无效)显示到目标区域,并为容器设置溢出隐藏。同时,为了让控件可被点击,我们让file处于较高的层并设置透明,只让容器样式可见,以此达到视觉与交互风格的统一。见代码:

    <style type="text/css">
      .container{
          font-family: "microsoft yahei";
          position: relative;
          width:200px;
          height: 80px;
          border:1px solid #ccc;/*为了看上去明显*/
          overflow: hidden;
          line-height: 80px;
          font-size: 16px;
          text-align: center;
          color: #fff;
          background-color: #ccc;
          border-radius: 4px;
      }
      .container:hover{
          background-color: #eee;
      }
      #myFile{
          position: absolute;
          font-size: 300px;
          cursor: pointer;
          right:0;
          top:0;
          opacity: 0;
          filter: alpha(opacity=0);
    }
    </style> <div class="container"> <input type="file" name="myFile" id="myFile" value="" /> 选择文件
    </div>

      这样我们基本上解决了以上所说的问题了。

      HTML5到来之前,我们对于file控件可以利用的有用数据也就是value属性了,H5file控件新增了files属性,该属性包含file控件选择的文件对象的集合,其中包括上次修改时间、名称、大小等信息。这极大地方便了我们开发者,还记得以前在公司做一个项目,要控制上传文件大小的时候还需要借助于flash来实现,否则只能等文件上传到服务端了再判断大小,结果很多时候上传了一个很大的文件,页面加载了半天(向后台传递需要走网络,比较耗时),最后还是告诉我文件过大。试想,这样的体验用户孰忍直视?(PSIE9不支持files属性)

      然而随着技术的发展,我们发现了另外一种可能更符合用户操作习惯的上传文件的方式:拖拽。现在已经有很多网站支持这种方式了。我们看一个演示的例子:

      

    <style>
                html,body,div{
                    margin:0;
                    padding: 0;
                }
                #file{
                    display: none;
                }
                .up-area{
                    margin:50px auto;
                    border: 1px dashed #ccc;
                    background-color: #eee;
                    width:600px;
                    height:400px;
                    line-height: 400px;
                    text-align: center;
                    color: #666;
                    cursor: pointer;
                }
                .up-area:hover{
                    background-color: #ddd;
                }
            </style>
    <input type="file" id="file"/>
            <div class="up-area" id="upArea"></div>
            <script type="text/javascript">
                (function(){
                    var area= document.getElementById("upArea"),
                        file = document.getElementById("file");
                    function uploadFile(fs){
                        console && console.log(fs);
                    }
                    area.onclick = function(){
                        console && console.log("click");
                        file.click();
                    }
                    file.onchange=function(){
                        uploadFile(this.files);
                    }
                    area.ondragenter = function(e){
                        this.className = "up-area hover";
                        e.preventDefault();
                    }
                    area.ondragover = function(e){
                        e.preventDefault();
                    }
                    area.ondrop = function(e){
                        e.preventDefault();
                        console && console.log("drop");
                        var dt = e.dataTransfer;
                        this.className = "up-area";
                        uploadFile(dt.files);
                    };
                })();
    
    </script>

      将文件拖至灰色虚线区域即可查看效果,这里我们主要关注的是divondrop事件,我们看到files属性并不是来自file控件,而是dataTransfer对象,我们看到,H5貌似又给我们提供了一种file控件之外的文件上传途径。

      那我们继续用用吧!

      我们知道,一般的上传文件过程是这样的:点击选择文件或直接将文件拖拽至区域内,触发文件上传,文件异步发送至服务器,待服务器处理完毕,返回消息显示到页面上。

      传统的文件上传要实现异步,通常有两种途径(iframe模拟、flash插件)。我们这里都不展示了,我们用FormData,用js创建一个表单对象,并向其中添加表单数据,结合XMLHttpRequest对象将表单异步提交。

      看代码:

    function uploadFile(fs){
                    var len = fs.length;
                    for(var i=0;i<len;i++){
                        sendFile(fs[i]);
                    }
                }
                function sendFile(file){
                    var xhr = new XMLHttpRequest(),
                        fd = new FormData();//ie10+ supported
                    fd.append('file',file);
                    xhr.onreadystatechange=function(){
                        if(xhr.readyState == 4 && xhr.status == 200){
                            consoleDiv.innerHTML += "<br/>" + xhr.responseText;//多文件
                        }
                    }
                    xhr.open("POST",'upload.php');
                    xhr.send(fd);
                }
                file.onchange = function(){//file控件属性改变时触发上传
                    uploadFile(this.files);
                }
                area.ondrop = function(e){//拖拽区域拖入文件时触发上传
                    e.preventDefault();
                    var dt =e.dataTransfer;
                    uploadFile(dt.files);
                }

      代码内容比较简单,不再赘述……需要注意的一点就是FormDataIE系列浏览器里,9完全不支持,1011都是部分支持。

      说到这里,与文件上传相关的,我们还想看一个H5新增的对象:FileReaderjs创建FileReader对象比较简单:var reader = new FileReader();通过FileReader对象可以访问文件,看一个简单的例子:

    var rd = new FileReader();
    rd.onload=function(e){
    console
    && console.log(e.target.result);
    }
    rd.readAsText(file);

      以上代码中file参数是一个file对象,可以是File控件的file属性中FileList中的一个,也可以是dataTransferfiles属性中FileList中的一个。

      关于FileReader更多的内容同学们可以自己搜寻,先到这里了。由于怕明天会加班,没时间写博,故而提前了一天。

  • 相关阅读:
    WordPress BackWPup插件‘tab’参数跨站脚本漏洞
    Microsoft Windows 远程权限提升漏洞(CVE-2013-3175)(MS13-062)
    Microsoft Internet Explorer 内存破坏漏洞(CVE-2013-3193)(MS13-059)
    Microsoft Internet Explorer 远程代码执行漏洞(CVE-2013-3186)(MS13-059)
    Monkey ‘mk_request_header_process’函数输入验证漏洞
    PHP Sessions子系统会话固定漏洞
    WordPress HMS Testimonials 多个跨站脚本漏洞和跨站请求伪造漏洞
    WordPress A Forms插件HTML注入漏洞和跨站请求伪造漏洞
    C++ 循环!循环类型+循环控制语句+无限循环!
    入职薪水对程序员的影响有多大,你根本不知道!入职指南,了解一下!
  • 原文地址:https://www.cnblogs.com/w3cape/p/4703355.html
Copyright © 2011-2022 走看看