首页

拖拽上传

站长
2019-01-24  阅读 31

拖拽上传应用主要使用了以下 HTML5技术:

  • Drag&Drop : HTML5基于拖拽的事件机制.

  • File API : 可以很方便的让 Web 应用访问文件对象, File API 包括FileList、Blob、File、FileReader、URI scheme, 本文主要讲解拖拽上传中用到的 FileList 和 FileReader 接口。

  • FormData : FormData 是基于 XMLHttpRequest Level 2的新接口, 可以方便 web 应用模拟 Form 表单数据,最重要的是它支持文件的二进制流数据, 这样我们就能够通过它来实现 AJAX 向后端发送文件数据了。

Drag和Drop§

关于这个拖拽上传,其实国外有很多网站已经有这样的应用, 最早推出拖拽上传应用的是 Gmail, 它支持标准浏览器下拖拽本地文件到浏览器中作为邮件的附件发送, 但其实现在利用HTML5的功能实现,主要借助于新版支持的浏览器来实现, IE还是弱很多

H5的Drag和Drop事件:

过去我们想实现网页中的拖拽效果,基本上都是使用DOM事件模型中的mousedown、mousemove、mouseup的事件监听来模拟拖拽效果,为了实现实时的拖拽移动效果,还要不停地获取鼠标的坐标,还要不停的修改元素的位置,代码要堆很多,而且性能上也很不好(不停地修改元素位置会导致页面reflow,除非绝对定位),现在有了h5原生的Drag和Drop事件,可以自由的玩耍了。

Drag和Drop包括以下事件:

  • dragstart: 要被拖拽的元素开始拖拽时触发,这个事件对象是被拖拽元素
  • dragenter: 拖拽元素进入目标元素时触发,这个事件对象是目标元素
  • dragover: 拖拽某元素在目标元素上移动时触发,这个事件对象是目标元素
  • dragleave: 拖拽某元素离开目标元素时触发,这个事件对象是目标元素
  • dragend: 在drop之后触发,就是拖拽完毕时触发,这个事件对象是被拖拽元素
  • drop:将被拖拽元素放在目标元素内时触发,这个事件对象是目标元素完成一次成功页面元素拖拽的行为事件过程:

dragstart –> dragenter –> dragover –> drop –> dragend

//要想实现拖拽,首页需要阻止浏览器默认行为,一共四个事件
$(document).on({
    dragleave:function(e){    //拖离
        e.preventDefault();
    },
    drop:function(e){        //放下
        e.preventDefault();
    },
    dragenter:function(e){    //拖进
        e.preventDefault();
    },
    dragover:function(e){    //拖来拖去
        e.preventDefault();
    }
});

获取文件数据H5-File-API§

File API 中的 FileList 接口,它主要通过两个途径获取本地文件列表: 一种是 <input type="file">的表单形式, 一种是 e.dataTransfer.files 拖拽事件传递的文件信息

var fileList = e.dataTransfer.files;

// 使用files 方法将会获取到拖拽文件的数组形势的数据,
// 每个文件占用一个数组的索引,如果该索引不存在文件数据,将返回 null 值。
// 可以通过length属性获取文件数量.
var fileNum = fileList.length;

// 文件类型
fileList[0].type.indexOf (’image’);

AJAX 上传图片(file.getAsBinary & FormData)§

file.getAsBinary获取文件流很简单,但是要想上传数据,就要模拟一下表单的数据格式了,首先看看模拟表单的js代码, FormData模拟表单数据时更是简洁,不用麻烦的去拼字符串,而是直接将数据 append 到 formdata 对象中即可

xhr = new XMLHttpRequest();
xhr.open("post", "test.php", true);
xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");

var fd = new FormData();
fd.append('ff', fileList[0]);

xhr.send(fd);

示例§

<!DOCTYPE HTML>
<html>

<head>
    <meta charset="utf-8">
    <title>拖拽上传</title>
    <script src="https://cdn.bootcss.com/jquery/1.7.1/jquery.min.js"></script>
    <style>
    .dashboard_target_box {
        width: 250px;
        height: 105px;
        border: 3px dashed #E5E5E5;
        text-align: center;
        position: absolute;
        z-index: 2000;
        top: 0;
        left: 0;
        cursor: pointer
    }

    .dashboard_target_messages_container {
        display: inline-block;
        margin: 12px 0 0;
        position: relative;
        text-align: center;
        height: 44px;
        overflow: hidden;
        z-index: 2000
    }

    .dashboard_target_box_message {
        position: relative;
        margin: 4px auto;
        font: 15px/18px helvetica, arial, sans-serif;
        font-size: 15px;
        color: #999;
        font-weight: normal;
        width: 150px;
        line-height: 20px
    }

    .dashboard_target_box.over {
        border: 3px dashed #000;
        background: #ffa;
    }

    .dashboard_target_box.over #dtb-msg1 {
        color: #000;
        font-weight: bold
    }

    #dtb-msg2 {
        color: orange
    }
    </style>
</head>

<body>
    <div id="target_box" class="dashboard_target_box">
        <div id="drop_zone_home" class="dashboard_target_messages_container">
            <p id="dtb-msg2" class="dashboard_target_box_message" style="top:-44px">选择你的图片<br>
                开始上传</p>
            <p id="dtb-msg1" class="dashboard_target_box_message" style="top:-44px">拖动图片到<br>
                这里</p>
        </div>
    </div>

     <script>
    $(document).ready(function() {

        //设计一段比较流行的滑动样式
        $('#drop_zone_home').hover(function() {
            $(this).children('p').stop().animate({ top: '0px' }, 200);
        }, function() {
            $(this).children('p').stop().animate({ top: '-44px' }, 200);
        });


        //要想实现拖拽,首页需要阻止浏览器默认行为,一个四个事件。
        $(document).on({
            dragleave: function(e) { //拖离
                e.preventDefault();
                $('.dashboard_target_box').removeClass('over');
            },
            drop: function(e) { //拖后放
                e.preventDefault();
            },
            dragenter: function(e) { //拖进
                e.preventDefault();
                $('.dashboard_target_box').addClass('over');
            },
            dragover: function(e) { //拖来拖去
                e.preventDefault();
                $('.dashboard_target_box').addClass('over');
            }
        });

        //================上传的实现
        var box = document.getElementById('target_box'); //获得到框体

        box.addEventListener("drop", function(e) {

            e.preventDefault(); //取消默认浏览器拖拽效果

            var fileList = e.dataTransfer.files; //获取文件对象
            //fileList.length 用来获取文件的长度(其实是获得文件数量)

            //检测是否是拖拽文件到页面的操作
            if (fileList.length == 0) {
                $('.dashboard_target_box').removeClass('over');
                return;
            }
            //检测文件是不是图片
            if (fileList[0].type.indexOf('image') === -1) {
                $('.dashboard_target_box').removeClass('over');
                return;
            }

            xhr = new XMLHttpRequest();
            xhr.open("post", "test.php", true);
            xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");

            var fd = new FormData();
            fd.append('ff', fileList[0]);

            xhr.send(fd);

        }, false);

    });
    </script>
</body>

</html>

test.php

<?php
if(!empty($_FILES["ff"])){
    move_uploaded_file(
        $_FILES["ff"]["tmp_name"],$_FILES["ff"]["name"]
    );
}
?>
请勿发布不友善或者负能量的内容。与人为善,比聪明更重要!