4

In Firefox, if I drag an image into a contenteditable field from the desktop, it will be embedded as base64 TO the HIGHLIGHTED cursor position.

JSFiddle: http://jsfiddle.net/zupa/YrwsS/

Now in Chrome, the image is opened by the browser (pageload, try in same fiddle).

Thanks to the HTML5 you can catch the drop event, and catch the image with it. But if I stop browsers default behavior, I am stuck not knowing where the user wanted to drop it.

Can you suggest a workaround?

zupa
  • 12,809
  • 5
  • 40
  • 39

1 Answers1

13

If you can get the co-ordinates of the drop location (which I assume must be possible), you can do it as follows (untested). I'm assuming you've got the co-ordinates of the drop location relative to the viewport as variables x and y and the dropped image as the variable img:

Demo: http://jsfiddle.net/KZqNj/

Code:

var range;

// Try the standards-based way first
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
else if (document.caretRangeFromPoint) {
    range = document.caretRangeFromPoint(x, y);
    range.insertNode(img);
}
// Finally, the IE way
else if (document.body.createTextRange) {
    range = document.body.createTextRange();
    range.moveToPoint(x, y);
    var spanId = "temp_" + ("" + Math.random()).slice(2);
    range.pasteHTML('<span id="' + spanId + '">&nbsp;</span>');
    var span = document.getElementById(spanId);
    span.parentNode.replaceChild(img, span);
}

This will work in recent-ish WebKit, Opera and Mozilla browsers, although only Firefox has an implementation of document.caretPositionFromPoint().

References:

Tim Down
  • 318,141
  • 75
  • 454
  • 536
  • Oh thank you so much I was really stuck with that! For others, in Chrome it was rather `document.caretRangeFromPoint(x, y)` and `range.setStart(pos.startContainer, pos.startOffset)` – zupa Jun 06 '12 at 16:20
  • @zupa: Ah, right. That's WebKit's own proprietary method; I thought they'd implemented the standards-based one now as well, but I could be wrong. Glad to help, anyway. – Tim Down Jun 06 '12 at 16:59
  • no worries, you pointed me in the right direction, that was all I needed, really! – zupa Jun 06 '12 at 21:02
  • The code works until IE11 is released. I get an "unspecified error" in range.moveToPoint() in IE 11. Both document.caretRangeFromPoint and document.caretPositionFromPoint are not available in IE11. Any suggestion? Thanks. – clam Feb 05 '14 at 19:22
  • @clam: Grr. After the progress made by IE 9 and 10 in eliminating compatibility issues, IE 11 seems to have introduced new problems. I'll look into it. – Tim Down Feb 05 '14 at 22:14
  • @clam: I think it's a jsFiddle thing (possibly something to do with the iframes? I haven't looked into it). It works fine in IE 11 on a standalone page, and in JS Bin: http://jsbin.com/kipa/1 – Tim Down Feb 06 '14 at 00:02
  • @TimDown Any updated IE 11 problem "unspecified error" . I am also trying same code on page where there are many contenteditables are used. But sadly IE11 is giving "unspecified error" error – maj Mar 02 '15 at 04:49
  • @maj: I'll have a look next time I have IE 11 available to me, which will be next week. – Tim Down Mar 02 '15 at 15:13
  • @TimDown Thanks time. Meanwhile i used the custom code here for Opera. Worked on IE also http://stackoverflow.com/questions/3189812/creating-a-collapsed-range-from-a-pixel-position-in-ff-webkit/13527512#13527512 – maj Mar 03 '15 at 06:53
  • I'm getting "unspecified error" for IE 11 too. How would a workaround integrated with Tim's code above look? – mozgras Mar 23 '15 at 03:46