Ben Dilts
Ben Dilts

Reputation: 10745

Accept drag & drop of image from another browser window

In Javascript, I know how to set up a drag & drop target that accepts file uploads from the user's computer. How can I set up a drop target that accepts images that are dragged from another website? All I need to know is the URL of the image that they've dragged.

I know this is possible, since Google Docs accepts image drops from other websites. Any idea how they're doing it?

Upvotes: 35

Views: 19195

Answers (6)

Darin Dimitrov
Darin Dimitrov

Reputation: 1038820

UPDATE:

It looks like there are differences between Chrome on Windows and MacOS. On Windows dataTransfer.getData('Text'); works but not on MacOS. dataTransfer.getData('URL'); should work on both.


OLD answer:

You could define a drop zone:

<div id="dropbox">DropZone => you could drop any image from any page here</div>

and then handle the dragenter, dragexit, dragover and drop events:

var dropbox = document.getElementById('dropbox');

dropbox.addEventListener('dragenter', noopHandler, false);
dropbox.addEventListener('dragexit', noopHandler, false);
dropbox.addEventListener('dragover', noopHandler, false);
dropbox.addEventListener('drop', drop, false);

function noopHandler(evt) {
    evt.stopPropagation();
    evt.preventDefault();
}
function drop(evt) {
    evt.stopPropagation();
    evt.preventDefault(); 
    var imageUrl = evt.dataTransfer.getData('Text');
    alert(imageUrl);
}

​ It is inside the drop event handler that we are reading the image data from the dataTransfer object as Text. If we dropped an image from some other webpage this text will represent the url of the image.

And here's a live demo.

Upvotes: 47

klues
klues

Reputation: 937

As the other answers correctly state: It normally depends on the CORS-Settings of the server if drag & drop from another browser window is possible (Access-Control-Allow-Origin has to be set).

However I've just found out by chance that it's possible to drap & drop any images from a Firefox (current version 68.0.1) to a Chrome window (current version 76.0.3809) and process it in Javascript, regardless if CORS headers are set or not.

See working example (based on jsfiddle of Darin Dimitrov) which accepts and directly shows images from:

  1. drag and drop from local computer (e.g. from file explorer)
  2. drag and drop from other website, if CORS headers are set, e.g. an image from https://imgur.com/
  3. drag and drop any images from Firefox window to Chrome window:
    • open jsfiddle demo in Chrome
    • open e.g. google image search in Firefox and search for any image
    • click on the image for bigger preview
    • drag & drop the preview image to the jsfiddle demo in Chrome

However this seems to be kind of a bug of Firefox and therefore I would not rely on this behaviour in an productive application.

Upvotes: 1

B Λ R T
B Λ R T

Reputation: 174

Here's my solution to the problem: Dropzone js - Drag n Drop file from same page

Please do keep in mind that ability to drag an image from another domain depends on their CORS setup.

Upvotes: 3

Luke Madhanga
Luke Madhanga

Reputation: 7457

Although you are able to accept the drag and drop of an image from another website, you are unable to do any processing of it (e.g. converting it to a base64 string using the canvas) (as of 21st August 2014) because of various cross-origin policy issues.

var dt = event.dataTransfer;
var url = dt.getData('url');
if (!url) {
    url = dt.getData('text/plain');
    if (!url) {
        url = dt.getData('text/uri-list');
            if (!url) {
                // We have tried all that we can to get this url but we can't. Abort mission
                 return;
             }
         }
     }

Even Google can't get around this - If you use gmail, you can drag and drop an image from another location in to the email body, but all this does is create an <img/> element with its src set to url (from the code above).

However, I've created a plugin that allows you to fake it cross-origin drag and drop. It requires a PHP backend.

Read the article I wrote on it here https://coderwall.com/p/doco6w/html5-cross-origin-drag-and-drop

Upvotes: 4

DanJGer
DanJGer

Reputation: 514

Some browsers use text/plain some use text/html as well

This code should pull any text or image source url on the latest Chrome, FF on Mac and PC.

Safari doesn't seem to give the URL so if someone knows how to get it let me know.

I'm still working on IE.

function getAnyText(theevent) {
//see if we have anything in the text or img src tag
    var insert_text;
    var location = theevent.target;
    var etext;
    var ehtml;
    try {
            etext = theevent.dataTransfer.getData("text/plain");
    } catch (_error) {}
    try {
            ehtml = theevent.dataTransfer.getData("text/html");
    } catch (_error) {}
    if (etext) {
            insert_text = etext;
    } else if (ehtml) {
            object = $('<div/>').html(ehtml).contents();
            if (object) {
                    insert_text =  object.closest('img').prop('src');
            }
    }
    if (insert_text) {
            insertText(insert_text,location);
    }
}

Upvotes: 2

zackdever
zackdever

Reputation: 1642

function drop(evt) {
    evt.stopPropagation();
    evt.preventDefault();
    var imageUrl = evt.dataTransfer.getData('URL');  // instead of 'Text'
    alert(imageUrl);
}

Seems to work in Firefox, Safari, and Chrome on Mac. Also works in Firefox, IE, and Chrome in Windows.

Updated fiddle

Upvotes: 4

Related Questions