在可编辑元素中实现拖放事件

4
当用户将内容拖放到contentEditable元素中时(在拖动后),会触发哪个事件?
我说的是普通的拖放,而不是HTML5拖放(其中任何元素都可以被设置为可拖动);使用情况很简单:
- 页面上有一个contentEditable div,用作编辑器 - 用户从当前页面或另一个页面,或另一个浏览器窗口拖放一些HTML(因此没有“源”对象的概念:源可以来自浏览器外部) - 我需要被通知内容已经被拖放到contentEditable div中,以便我可以对其进行操作(清理它)
我可以轮询div,看看是否有任何不干净的东西,但这很耗费资源并且很“丑陋”;肯定有一个事件在拖放发生时触发...?

2
为什么你不想要HTML5的拖放事件?ondrop正是你在contentEditable中所需要的... - ldiqual
因为我需要它在非HTML5浏览器上运行。 - Bambax
2个回答

7
我在编写tinyMCE插件时遇到了同样的问题。我发现跟踪内容编辑区域中元素的拖放最好的方法是监听contentEditable元素上的“DOMNodeInserted”事件。
请注意,当执行拖放操作时,此元素由contentEditable元素触发,因此其目标属性设置为此元素。您可以通过检查event.originalEvent.target属性来检索移动的元素。
请注意,此事件在放置完成且已插入放置元素后触发。
$('#editor').bind('DOMNodeInserted', function(event){
      if(event.originalEvent && event.originalEvent.target){
        var target = $(event.originalEvent.target);
        //now you can check what has been moved
      }
});

非常感谢!每个节点插入时都会触发事件,但是仅通知“已执行拖放”会更好,但现在这也可以正常工作!;-) - Bambax
1
这是一个现在可行的合理解决方案。请注意,IE < 9不支持DOM突变事件,因此在这些浏览器中无法工作。此外,未来的浏览器很可能会删除DOM突变事件并用其他东西替换它们(浏览器制造商不喜欢它们并认为它们是一个错误)。 - Tim Down
确实规范如此说明:“本规范描述了变异事件以便于参考和完整性的遗留行为,但不建议使用MutationEvent接口和MutationNameEvent接口”(http://www.w3.org/TR/DOM-Level-3-Events/#events-mutationevents) - Bambax
1
对于IE 7-8,有什么好的方法呢?(忘记IE6 - 尽管contentEditable是在IE5中引入的,我认为)。 - Bambax
MutationObserver对象是否是此事件的正确替代品?https://developer.mozilla.org/zh-CN/docs/Web/API/MutationObserver - Alexis Wilke

0

这里有一个解决方案,只需使用ondrop事件。 ondrop事件有效,但问题在于它在内容更改之前触发。因此,解决方法是使用带有一点延迟的setTimeout。

这是您可以测试的解决方案片段。当您将图像放在顶部div上后,该div的内容将被复制到底部div中。阅读代码中的注释,它提供了有关如何处理延迟的更多信息。

function doSomething() {
   document.getElementById('result').innerHTML=document.getElementById('edt').innerHTML;
}
function takeCareOfDrop() {
  setTimeout(function () { doSomething(); }, 100); // <-- optional
  setTimeout(function () { doSomething(); }, 1000);
  
  /* 
  I call doSomething two times above. 
  Once after 100 ms and then again after 1000 ms.
  
  If it is not acceptable to call it twice, then 
  only use 1000 ms, or some delay appropriate for you.
  
  If it IS acceptable to call it twice, then the 
  advantage of doing it twice is this:
    In my case I tried 1 ms, but that was not enough. 
    So I suspected that in some cases 100 ms might not 
    be enough either. But 1000 ms is a bit long. So I 
    made it call doSomething two times, once after 
    100 ms and one more time after 1000 ms, just to be 
    sure. In this way, it mostly happens 
    instantly (100 ms), but in some cases with a bit 
    of a delay (1000 ms).
  */
}
div {height:65px;border:1px solid red;}
Try to drop a small image on the top div. <img src="data:image/png;base64,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" alt="">
<div id="edt" contenteditable="true" ondrop="takeCareOfDrop()"><p>Lorem ipsum</p></div>

<div id="result"</div>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接