jQuery HTML5 文件拖放

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12954529/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 12:09:38  来源:igfitidea点击:

jQuery HTML5 file drag and drop

jqueryhtmldrag-and-drop

提问by Jens T?rnell

I have looked at many scripts for uploading images to the server with AJAX with drag and drop. The scripts I found are not jQuery, are quite large and don't do exactly what I want.

我已经查看了许多用于使用 AJAX 通过拖放将图像上传到服务器的脚本。我发现的脚本不是 jQuery,它们非常大并且不完全符合我的要求。

In the future it should upload an image with jQuery, AJAX and PHP.

将来它应该使用 jQuery、AJAX 和 PHP 上传图像。

My question

我的问题

In many of the example I've looked at e.dataTransfer.files work. In my case it don't. Do I need to bind it somehow?

在许多例子中,我看过 e.dataTransfer.files 的工作。就我而言,它没有。我需要以某种方式绑定它吗?

I want jQuery as much as possible.

我尽可能地想要 jQuery。

JsFiddle

提琴手

Play around as much as you like...

随心所欲地玩耍……

http://jsfiddle.net/AMjEz/

http://jsfiddle.net/AMjEz/

Code

代码

<html>
    <head>
        <style type="text/css">
            #dropzone {
                border: 2px dashed #ccc;
                width: 300px;
                height: 200px;
            }
        </style>
        <script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
        <script type="text/javascript">
            jQuery(document).ready(function($) {
                $('#dropzone').on({
                    dragenter: function(e) {
                        $(this).css('background-color', 'lightBlue');
                    },
                    dragleave: function(e) {
                        $(this).css('background-color', 'white');
                    },
                    drop: function(e) {
                        e.stopPropagation();
                        e.preventDefault();
                        console.log(e.dataTransfer.files);
                    }
                });
            });
        </script>
    </head>
    <body>
        <div id="dropzone">
            Drop files here
        </div>
    </body>
</html>

采纳答案by Jens T?rnell

I found out that it's a bug in jQuery.1.8. This row should be before $('.dropzone').

我发现这是 jQuery.1.8 中的一个错误。这一行应该在$('.dropzone').

$.event.props.push('dataTransfer');

Final HTML code

最终的 HTML 代码

<html>
    <head>
        <style type="text/css">
            .dropzone {
                border: 2px dashed #ccc;
                width: 300px;
                height: 200px;
            }
        </style>
        <script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
        <script type="text/javascript">
            jQuery(document).ready(function($) {
                var filename = '';
                var image_data = '';

                $.event.props.push('dataTransfer');
                $('.dropzone').on({
                    dragenter: function(e) {
                        $(this).css('background-color', 'lightBlue');
                    },
                    dragleave: function(e) {
                        $(this).css('background-color', 'white');
                    },
                    drop: function(e) {
                        e.stopPropagation();
                        e.preventDefault();

                        var file = e.dataTransfer.files[0];
                        var fileReader = new FileReader();

                        var this_obj = $(this);

                        fileReader.onload = (function(file) {
                            return function(event) {
                                // Preview
                                filename = file.name;
                                image_data = event.target.result;
                                $(this_obj).next().html('<a href="#" class="upload-file">Upload file</a>');
                                $(this_obj).html('<img style="max-width: 200px; max-height: 200px;" src="' + event.target.result + '">');
                            };
                        })(file);

                        fileReader.readAsDataURL(file);         
                    }
                });

                // Upload file
                $(".upload-file").live("click", function(e){
                    e.preventDefault();

                    var this_obj = $(this);
                    var image_data = $(this_obj).parent().prev().find('img').attr('src');

                    $.post(
                        'send_image.php',
                        {
                            data: image_data,
                            filename: filename
                        }, function(response){  
                            $(this_obj).parent().prev().html(response);
                            $(this_obj).remove();
                        }
                    );

                    //console.log('ok');
                });

            });
        </script>
    </head>
    <body>
        <!-- Multiple dropzones -->
        <div class="dropzone">
            Drop files here
        </div>
        <div id="meta"></div>
        <div class="dropzone">
            Drop files here
        </div>
        <div id="meta"></div>
    </body>
</html>

PHP code in send_image.php

send_image.php 中的 PHP 代码

<?php
$raw_data = $_POST['data'];

file_put_contents(
    'image123.jpg',
    base64_decode( 
        str_replace('data:image/jpeg;base64,', '', $raw_data)
    )
);
?>

<br>

<?php echo '<img style="max-width: 200px; max-height: 200px;" src="' . 'image123.jpg' . '">'; ?>

回答by Ron van der Heijden

I wrote an extension for my application.

我为我的应用程序编写了一个扩展。

// Custom file drop extension
$.fn.extend({
    filedrop: function (options) {
        var defaults = {
            callback : null
        }
        options =  $.extend(defaults, options)
        return this.each(function() {
            var files = []
            var $this = $(this)

            // Stop default browser actions
            $this.bind('dragover dragleave', function(event) {
                event.stopPropagation()
                event.preventDefault()
            })

            // Catch drop event
            $this.bind('drop', function(event) {
                // Stop default browser actions
                event.stopPropagation()
                event.preventDefault()

                // Get all files that are dropped
                files = event.originalEvent.target.files || event.originalEvent.dataTransfer.files

                // Convert uploaded file to data URL and pass trought callback
                if(options.callback) {
                    var reader = new FileReader()
                    reader.onload = function(event) {
                        options.callback(event.target.result)
                    }
                    reader.readAsDataURL(files[0])
                }
                return false
            })
        })
    }
})

And we can use it like this

我们可以像这样使用它

// Event listener filedropper
$('.dropbox').filedrop({
    callback : function(fileEncryptedData) {
        // a callback?
    }
})

Edit

编辑

If you want to drop multiple files, you should write a for loop around the FileReader like so:

如果你想删除多个文件,你应该围绕 FileReader 编写一个 for 循环,如下所示:

...
if(options.callback) {
    for (i = 0; i < files.length; i++) {
        var reader = new FileReader()
        reader.onload = function(event) {
            options.callback(event.target.result)
        }
        reader.readAsDataURL(files[0])
    }
}
...

JSFiddle: http://jsfiddle.net/646xe1m2/

JSFiddle:http: //jsfiddle.net/646xe1m2/

回答by Rachael

t?rnell

t?rnell

thanks for sharing you're code, it helped me immensely! For anyone else finding IE edge being a bother here's the final code I have from @jens-t?rnell and advice given on this post jQuery.on("drop") not firing

感谢分享你的代码,它对我帮助很大!对于其他发现 IE 边缘很麻烦的人,这里是我从 @jens-t?rnell 获得的最终代码以及在这篇文章中给出的建议jQuery.on("drop") not fire

  jQuery(document).ready(function($){
    var filename = '';
    var image_data = '';
    $.event.props.push('dataTransfer');

    $('.dropzone').on({
      dragover: function(e) {
        e.stopPropagation();
        e.preventDefault();
        $(this).addClass('highlight');
        console.log("t3");
        return false; //crucial for 'drop' event to fire
       },
      dragleave: function(e) {
        e.stopPropagation();
        e.preventDefault();
        $(this).removeClass('highlight');
        return false;
       },
       drop: function(e) {
         e.stopPropagation();
         e.preventDefault();
         var file = e.dataTransfer.files[0];
         var fileReader = new FileReader();

         var this_obj = $(this);

         fileReader.onload = (function(file) {
             return function(event) {
                 // Preview
                 filename = file.name;
                 image_data = event.target.result;
                 $(this_obj).next().html('<a href="#" class="upload-file">Upload file</a>');
                 $(this_obj).html('<img style="max-width: 200px; max-height: 200px;" src="' + event.target.result + '">');
             };
         })(file);
         fileReader.readAsDataURL(file);
         return false;
       }
    });

    // Upload file
    $(".upload-file").live("click", function(e){
       e.preventDefault();

       var this_obj = $(this);
       var image_data = $(this_obj).parent().prev().find('img').attr('src');

       $.post(
           'upload-file.php',
           {
               data: image_data,
               filename: filename
           }, function(response){
               $(this_obj).parent().prev().html(response);
               $(this_obj).remove();
           }
       );

     console.log('ok');
 });
  <div class="dropzone" id="dropzone"><p>Drop files here to upload them.</p></div>
      <div id="meta"></div>