JQuery - 拖放文件 - 如何获取文件信息?

时间:2011-12-02 22:24:00

标签: php jquery ajax file-upload drag-and-drop

有兴趣使用JQuery / AJAX / PHP构建我自己的drag'n'drop文件上传器。

基本上我想要一个文件上传器,我的网站用户可以将文件从他们的计算机拖到我创建的div中,然后它会将文件上传到所选目的地。

我想从头开始构建它,而不是使用任何插件,以便我可以更好地操纵限制(文件类型,大小,目标文件夹等)。

谷歌没有运气,只有插件。无论如何可以引导我朝着正确的方向前进吗?

更新 好的,所以我想出了如何做我想做的事。只需将文件输入字段不透明度设置为1即可隐藏,您仍然可以将文件拖到该常规区域中,如果您点击文本字段,它将捕获它。但是,我想知道如何增加文件输入字段的高度/宽度(在文件上尝试了基本的css,但它只增加了'浏览'按钮的大小,而不是你可以将文件放入的实际字段。任何想法如何做到这一点? 我基本上想要一个大的方形div,上面写着'Drop file here'。所以我需要调整输入字段的大小。

3 个答案:

答案 0 :(得分:5)

您可以使用HTML5 dragenterdragleave事件来创建dropzone 然后通过在dropzone中放置一个文件输入并使用CSS隐藏它,您可以在输入的change事件触发时上传文件,如下所示

var dropzone = $("#dropzone"),
    input    = dropzone.find('input');

dropzone.on({
    dragenter : dragin,
    dragleave : dragout
});

input.on('change', drop);

function dragin(e) { //function for drag into element, just turns the bix X white
    $(dropzone).addClass('hover');
}

function dragout(e) { //function for dragging out of element                         
    $(dropzone).removeClass('hover');
}

function drop(e) {
    var file = this.files[0];
    $('#dropzone').removeClass('hover').addClass('dropped').find('img').remove();

    // upload file here
}

FIDDLE

答案 1 :(得分:3)

就在这里,就像我最近几天一样。根据我的理解,如果您通过jQuery绑定drop事件,则需要通过浏览jQuery提供的事件中的event.dataTransfer对象来访问该event.originalEvent对象。

示例:

在此我同时绑定dragoverdrop事件,因为这是阻止它执行默认操作所必需的(在此处找到解决方案:Prevent the default action. Working only in chrome)< / p>

$('#dropzone').bind('dragover drop', function(event) {
    event.stopPropagation(); 
    event.preventDefault();
    if (event.type == 'drop') {
        console.log(event.originalEvent.dataTransfer.files);
    }
});

此外,似乎还有一个错误,如果console.log() event.dataTransfer(或event.originalEvent.dataTransfer)它的文件数组为空,则会在此处指出:event.dataTransfer.files is empty when ondrop is fired?

为了更好地回答OP的问题(我刚刚注意到其余部分,我知道它已经过时但有些人可能觉得这很有帮助):

我的实现是在jQuery中,所以我希望没关系:

var files = [];

// Attaches to the dropzone to pickup the files dropped on it. In mine this is a div.
$("#dropzone").bind('dragover drop', function(event) {
    // Stop default actions - if you don't it will open the files in the browser
    event.stopPropagation();
    event.preventDefault();

    if (e.type == 'drop') {
        files.push(event.originalEvent.dataTransfer.files);
    }
});

// Attach this to a an input type file so it can grab files selected by the input
$("#file-input").bind('change', function(event) {
    files.push(event.target.files);
});

// This is a link or button which when clicked will do the ajax request 
// and upload the files
$("#upload-button").bind('click', function(event) {
    // Stop the default actions
    event.stopPropagation();
    event.preventDefault();

    if (files.length == 0) {
        // Handle what you want to happen if no files were in the "queue" on clicking upload
        return;
    }

    var formData = new FormData();
    $.each(files, function(key, value) {
        formData.append(key, value);
    });

    $.ajax({
        url: 'upload-ajax',
        type: 'POST',
        data: formData,
        cache: false,
        dataType: 'json',
        processData: false, // Don't process the files - I actually got this and the next from an SO post but I don't remember where
        contentType: false, // Set content type to false as jQuery will tell the server its a query string request
        success: function(data, textStatus, jqXHR) { /* Handle success */ },
        error: function(jqXHR, textStatus, errorThrown) { /* Handle error */ }
    });

});

您还可以绑定到接受的答案中的其他事件,以执行效果,例如使dropzone淡入,以便您可以看到它(这是我的库的todo列表)。这是我使用的实际ajax文件上传的核心。

我真的没有一种方便的方法来测试它,但这本质上是我做的(我基本上从我一直在制作的库中获取所有代码并调整它以适应这里的通用代码块以一种易于理解的方式)。希望这可以帮助一些人。从这里开始实际上很容易继续并添加一个文件队列列表,能够从队列中删除文件,所以这应该是一个很好的起点。

答案 2 :(得分:0)

对于那些感兴趣的人,我发现这个教程/演示很有用:http://www.viget.com/inspire/custom-file-inputs-with-a-bit-of-jquery/

基本上使用<span>来覆盖默认输入字段。