This question has been answered elsewhere on this site: Precise Drag and Drop within a contenteditable
The solution there has code specific to each browser (via feature detection), and currently only works in Chrome and Firefox. For Chrome, a range needs to be computed from the mouse coordinates using document.caretRangeFromPoint
. For Firefox, the event object has the rangeParent
and rangeOffset
properties, which can be used to determine where the caret should be positioned.
document.addEventListener("drop", function(e) {
var sel = document.getSelection();
if(document.caretRangeFromPoint) { // Chrome
var range = document.caretRangeFromPoint(e.clientX,e.clientY);
sel.removeAllRanges();
sel.addRange(range);
} else if(e.rangeParent) { // Firefox
var range = document.createRange();
range.setStart(e.rangeParent, e.rangeOffset);
sel.removeAllRanges();
sel.addRange(range);
} else if(sel.rangeCount == 0) { // Default to at least not completely failing
var range = document.createRange();
sel.addRange(range);
}
// The selection is now in the right place - proceed with whatever the drop should do
});
This code is designed to work with the entire document being editable - for an editable div, you'll need to set the event listener on that div, and modify the fallback case to guarantee that the selection is inside the div.