有没有一种方法可以将文件拖放到DOM中,并在拖放操作期间检测鼠标指针在DOM中的光标位置/范围?
我可以轻松地捕获Drop并获取文件和内容,但似乎无法弄清楚如何将自定义HTML标记拖放到页面上的放置位置。该下拉菜单提供了鼠标位置,但问题是如何将其(或其他任何形式)转换为光标位置和范围,以便可以在其中粘贴文件的新链接(在动态保存之后)。
我的用例是,我正在使用Ace编辑器(或任何contentEditable区域),并试图将文件拖放到鼠标光标所在的位置的文档中。然后,我想捕获文件,并插入引用捕获文件数据的链接,在这种情况下,使用文件API捕获该数据,并使用Web浏览器控件将其存储在磁盘上。除了检测文本文档中的放置位置之外,我可以使所有内容都能正常工作。
那么,有什么想法如何从放置操作中获取选择范围?我有鼠标坐标,但是我不确定如何将它们与文本位置相关联,可以从该文本位置创建范围以将我的链接插入其中。
最佳答案
此答案部分解决了问题的Ace编辑器部分,但未解决如何使用原始DOM操作执行此操作的问题。我希望其他人对原始DOM有解决方案。
对于Ace Editor解决方案,它具有支持的API,这些API允许使用以下方式将PageX
和PageY
位置映射到编辑器文档中的物理行和列位置:
var pos = editor.renderer.screenToTextCoordinates(e.pageX, e.pageY)
使用该逻辑,可以使用以下代码将文件拖放到放置位置:
var $el = $("pre[lang]") // editor element
.on("dragover", function(e) {
$(this).addClass("hover");
return false;
})
.on("dragleave", function() {
$(this).removeClass("hover");
return false;
})
.on("drop", function(e) {
e = e.originalEvent;
e.preventDefault();
// grab the file
var file = e.dataTransfer.files[0];
// do something to save the file data to disk or server
var imageUrl = "somelinktoimage";
// Ace Editor logic
var pos = editor.renderer.screenToTextCoordinates(e.pageX, e.pageY);
var sel = te.editor.getSelection();
sel.selectToPosition(pos);
var range = sel.getRange();
range.setStart(pos.row,pos.column);
range.setEnd(pos.row, pos.column);
sel.setSelectionRange(range);
te.editor.getSession().replace(range, "![" + file.name + "](" + imageUrl + ")");
return false;
});