Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Drag and drop image file into contenteditable div: works fine in FF, fails miserably in Chrome

I have a contenteditable div, and I want the user to be able to drop an image file from their computer into the div. This works as expected in FF, but in chrome, rather than drop the file into the div, it navigates away from the page and opens the file in the browser. I feel like I must be missing something basic here, since facebook, gmail, etc., have file drag and drop that works in Chrome.

I am simply using

<div contenteditable='true'></div>

and here is a fiddle http://jsfiddle.net/Jt9LU/

Anything that I need to add in CSS, JS, jQuery, or the HTML markup would be appreciated, since it really seems like it must be something simple.

Tried in Chrome 34 and Chrome Canary 36

like image 266
chiliNUT Avatar asked Dec 14 '22 23:12

chiliNUT


1 Answers

Big thanks to RobM for pointing me in the right direction. Using the other SO answer you provided, and the tutorial link you provided, here is a solution working for me in FF and chrome

(See fiddle: http://jsfiddle.net/MWe8U/)

HTML

Content Editable Div:
        <div id='d' class='demo' contenteditable='true'>
        </div>

CSS

.demo{
    height:400px;
    border:1px solid black;
    overflow-y:scroll;
}

JS

        $(document).ready(function() {
            var handleDrag = function(e) {
                //kill any default behavior
                e.stopPropagation();
                e.preventDefault();
            };
            var handleDrop = function(e) {
                //kill any default behavior
                e.stopPropagation();
                e.preventDefault();
                //console.log(e);
                //get x and y coordinates of the dropped item
                x = e.clientX;
                y = e.clientY;
                //drops are treated as multiple files. Only dealing with single files right now, so assume its the first object you're interested in
                var file = e.dataTransfer.files[0];
                //don't try to mess with non-image files
                if (file.type.match('image.*')) {
                    //then we have an image,

                    //we have a file handle, need to read it with file reader!
                    var reader = new FileReader();

                    // Closure to capture the file information.
                    reader.onload = (function(theFile) {
                        //get the data uri
                        var dataURI = theFile.target.result;
                        //make a new image element with the dataURI as the source
                        var img = document.createElement("img");
                        img.src = dataURI;

                        //Insert the image at the carat

                        // Try the standards-based way first. This works in FF
                        if (document.caretPositionFromPoint) {
                            var pos = document.caretPositionFromPoint(x, y);
                            range = document.createRange();
                            range.setStart(pos.offsetNode, pos.offset);
                            range.collapse();
                            range.insertNode(img);
                        }
                        // Next, the WebKit way. This works in Chrome.
                        else if (document.caretRangeFromPoint) {
                            range = document.caretRangeFromPoint(x, y);
                            range.insertNode(img);
                        }
                        else
                        {
                            //not supporting IE right now.
                            console.log('could not find carat');
                        }


                    });
                    //this reads in the file, and the onload event triggers, which adds the image to the div at the carat
                    reader.readAsDataURL(file);
                }
            };

            var dropZone = document.getElementById('d');
            dropZone.addEventListener('dragover', handleDrag, false);
            dropZone.addEventListener('drop', handleDrop, false);
        });
like image 71
chiliNUT Avatar answered Dec 29 '22 00:12

chiliNUT