Checking HTML5 drag and drop file type

前端 未结 3 690
野趣味
野趣味 2021-02-08 09:52

I\'d like to change drop zone background color to green or red depending on whether the contained drag over payload contains supported file types (JPEG).

  • Do Ge

相关标签:
3条回答
  • 2021-02-08 10:20

    You can get the file types in Gecko and webkit supported browsers using file object.

    var files =e.dataTransfer.files||e.target.files; // File list
    

    The file object returns Name,Type and size. you can get last modified date too.

    var mimeType= files[0].type; //mime type of file list first entry
    
    0 讨论(0)
  • 2021-02-08 10:37

    Testing the type of a file in JavaScript is a bit of work, but new versions of the browsers now have the FileReader object that allows you to do that.

    There is an incomplete reference to my implementation which reads the buffer as uint8 bytes and then checks to see whether the input is a valid JPEG, GIF, PNG. Obviously, it will be enhanced with time. For a more complete version, look for the editor.js file in the editor plugin of the snapwebsites project. https://sourceforge.net/p/snapcpp/code/ci/master/tree/snapwebsites/plugins/editor/

    // The buffer is expected to be an ArrayBuffer() as read with a FileReader
    _buffer2mime: function(buffer)
    {
        buf = Uint8Array(buffer);
        if(buf[0] == 0xFF
        && buf[1] == 0xD8
        && buf[2] == 0xFF
        && buf[3] == 0xE0
        && buf[4] == 0x00
        && buf[5] == 0x10
        && buf[6] == 0x4A  // J
        && buf[7] == 0x46  // F
        && buf[8] == 0x49  // I
        && buf[9] == 0x46) // F
        {
            return "image/jpeg";
        }
        if(buf[0] == 0x89
        && buf[1] == 0x50  // P
        && buf[2] == 0x4E  // N
        && buf[3] == 0x47  // G
        && buf[4] == 0x0D  // \r
        && buf[5] == 0x0A) // \n
        {
            return "image/png";
        }
        if(buf[0] == 0x47  // G
        && buf[1] == 0x49  // I
        && buf[2] == 0x46  // F
        && buf[3] == 0x38  // 8
        && buf[4] == 0x39  // 9
        && buf[5] == 0x61) // a
        {
            return "image/gif";
        }
    
        // unknown
        return "";
    },
    
    _droppedImageAssign: function(e){
        var img,id;
        img = new Image();
        img.src = e.target.result;
        ++this._uniqueId;
        id="snap-editor-image-"+this._uniqueId;
        jQuery(img).hide().attr("id",id).appendTo(e.target.snapEditorElement);
        jQuery("#"+id).show();
    },
    
    _droppedImage: function(e){
        var mime, r, a, blob;
    
        mime = snapwebsites.EditorInstance._buffer2mime(e.target.result);
        if(mime.substr(0, 6) == "image/")
        {
            r = new FileReader;
            r.snapEditorElement = e.target.snapEditorElement;
            r.onload = snapwebsites.EditorInstance._droppedImageAssign;
            a = [];
            a.push(e.target.snapEditorFile);
            blob = new Blob(a, {type: mime}); // <- FORCE THE REAL MIME TYPE
            r.readAsDataURL(blob);
        }
    },
    
    jQuery("#some-object")
            .on("drop",function(e){
                // always prevent the default dropping mechanism
                // we handle the file manually all the way
                e.preventDefault();
                e.stopPropagation();
    
                // anything transferred on widget that accepts files?
                if(e.originalEvent.dataTransfer
                && e.originalEvent.dataTransfer.files.length)
                {
                    accept_images = jQuery(this).hasClass("image");
                    accept_files = jQuery(this).hasClass("attachment");
                    if(accept_images || accept_files)
                    {
                        for(i = 0; i < e.originalEvent.dataTransfer.files.length; ++i)
                        {
                            // read the image so we can make sure it is indeed an
                            // image and ignore any other type of files
                            r = new FileReader;
                            r.snapEditorElement = this;
                            r.snapEditorFile = e.originalEvent.dataTransfer.files[i];
                            r.onload = snapwebsites.EditorInstance._droppedImage;
                            // Get the first 64 bytes of the file to check the magic code
                            r.readAsArrayBuffer(r.snapEditorFile.slice(0, 64));
                        }
                    }
                }
    
                return false;
            })
    
    0 讨论(0)
  • 2021-02-08 10:38

    I don't think you can rely on the browser to give you the MIME type. It'd be much simpler if you checked the filename extension. :)

    If you really want to check the file type, read the payload using DataTransfer.getData() and check the leading bytes (PNG, GIF89, JFIF or something).

    0 讨论(0)
提交回复
热议问题