• 文件上传相关的事儿


    自从web进入了2.0的时代,文件上传的功能几乎是遍地开花。小到设置头像,大到网盘管理,都离不开文件上传的功能。今天小剧就来扒一扒和文件上传相关的事儿(本文不讨论swf的上传方式)。

    裸奔时代

    这里提到的是最原始,也是最基础的上传方式,form提交。只需指定methodactionenctype,再配合一个文件域(inputtype=“file”)即可完成上传。

    <form method="post" action="/ajax/upload" enctype="multipart/form-data>
        <input name="file" type="file">
        <input type="submit">
    </form>
    

    显而易见,这种上传方式是需要将文件提交到另一个接收上传的页面里。对的,你没有听错,是接收上传的页面,而不是上传接口。所有的接下来的流程必须在接收上传的页面上完成(或者有更精妙的处理方式,这里暂不讨论)。文件上传对于流程的打断其实是蛮严重的。

    石器时代

    聪明能干的前端工程师们为了解决页面跳转问题,找到了一个较为人性化的方式。因为form提交有一个属性,叫target。可用的属性值和a标签一样,也可以接受自定义名称。利用这个属性,即可完成form表单向特定的页面或iframe进行提交。通过监听iframe的返回值来判断上传结果,而不影响当前页面流程。

    <iframe id="uploadA" name="uploadA" src="about:blank"></iframe>
    <form method="post" action="/ajax/upload" enctype="multipart/form-data" target="uploadA">
        <input name="file" type="file">
        <input type="submit">
    </form>
    

    青铜器时代

    上传问题解决,这时候对美的追求也开始了。就像大伙儿知道的一样,文件域在各个浏览器下的外观其实是千差万别的。于是乎在上一时代的基础上,开始了艺术创作。既然需要统一上传按钮的外观,文件域又很难驯服,那就只能狠心的让文件域隐藏不可见,但又可以被用户点击。

    <div class="uploadBtn">
        <span>上传</span>
        <iframe id="uploadA" name="uploadA" src="about:blank"></iframe>
        <form method="post" action="/ajax/upload" enctype="multipart/form-data" target="uploadA">
            <input name="file" type="file" />
        </form>
    </div>
    
    .uploadBtn{
        position: relative;
         100px;
        height: 26px;
        text-align: center;
        line-height: 26px;
        background: #f70;
        overflow: hidden;
    }
    .uploadBtn span{
        color: #fff;
    }
    .uploadBtn input{
        position: absolute;
        top: 0;
        right: 0;
         200%;
        height: 100%;
    }
    #uploadA{
        position: absolute;
        left: -10px;
        display: block;
         0;
        height: 0;
        border- 0;
    }
    
    var iframe = $('#uploadA')[0];
    //文件变动,自动上传
    $('.uploadBtn input').on('change',function(){
        $(this).parents('form').submit();
    });
    //监听iframe onload事件
    if (iframe.attachEvent){
        iframe.attachEvent("onload", function(){
            //iframe.contentDocument
        });
    }else{
        iframe.onload = function(){
            //iframe.contentDocument
        };
    }
    

    通过这样一番改造,在cssjavascript的精心配合下,用户完全看不见了文件域的踪影,却又在不知不觉中使用着,由最传统的上传方式改造后的功能。

    这里简单提下文件域的处理

    外观就不说了,直接上交互。IE下,点击浏览按钮即可弹出系统文件选择器,而左侧大部分的区域需要双击才能生效,chrome下则是点击文件域下任意区域即可,firefox部分版本点击左侧无效。

    文件域在不同浏览器下的差异

    既然左侧区域这么不靠谱,直接用右侧作为点击区域好了,这就是上面的css使用靠右定位input的原因。

    这样子就足够了么?显然不。因为小剧前期参与的产品中,上传按钮区域较小,问题并未暴露出来,这里说下问题。

    还是IE,因为IE右侧的按钮宽度其实是个相对固定的大小,当上传按钮(给用户看的)宽度大于input的浏览按钮后,同样会出现双击才能选择文件的bug(我说我用过mousemove来解决这个问题你会信我)。

    火炮时代

    以上的解决是大多数web非插件的上传方式。经过小剧实践,又找到一种较为猥琐的触发方式。

    相信很多小伙伴都用过jQuery的trigger方法,用来主动触发一些事件还是很方便的。但是浏览器出于对用户的保护,很多高级事件是不会被响应的。比如移动端对输入框主动触发focus不会弹起软键盘,对文件域主动触发click不会弹出文件选择,等等。

    偶然的一次手贱,被我发现,只要是用户主动click页面任何一个位置,与此同时(必须在原生事件的回调中),主动触发文件域的click,是可以调起系统的文件选择器的。

    有了这一里应外合的同伙,上面费尽心机去勾搭鼠标、冒充按钮的事情都不用去做了。


    PS:目前的上传插件多数为swf,少部分为swf与html5配合使用。本文仅作为抛砖引玉,让小伙伴们了解下原生上传需要注意的几个关键点。

    转自:http://bh-lay.com/blog/14a2e2b6592

  • 相关阅读:
    finereport 文档
    FineRport 工作用
    SQL 排序
    fineReport
    python | Mysql 索引优化分析
    python | 缓存穿透、缓存雪崩和缓存击穿面试题
    python | Jenkins构建Spring Boot 详细步骤
    python | MySQL全面查询的正则匹配
    python | TCP 三次握手和四次挥手图解(有限状态机)
    python | 3款工具实现快速K8S开发
  • 原文地址:https://www.cnblogs.com/baixiaosheng/p/4195197.html
Copyright © 2020-2023  润新知