在contentEditable元素中拖放事件

时间:2011-09-02 08:06:35

标签: javascript events drag-and-drop contenteditable

在contentEditable元素中删除内容时(触发后)会触发什么事件?

我说的是普通的拖放,而不是HTML5拖放(任何元素都可以拖放);用例很简单:

  • 页面上有一个contentEditable div,用作编辑器
  • 用户从当前页面或其他页面或其他浏览器窗口拖放一些HTML(因此实际上没有任何“源”对象的概念:源可以来自浏览器外部)
  • 我需要收到通知,内容已被删除到contentEditable div中,以便我可以对其进行操作(清理它)

我可以轮询div,看看那里有什么东西不干净,但是它很贵而且“丑陋”;肯定有一个事件会在发生跌落时触发......?

2 个答案:

答案 0 :(得分:7)

我在编写tinyMCE插件时遇到了同样的问题。 我发现在contentEditable区域中跟踪元素拖放的最佳方法是在contentEditable元素上侦听'DOMNodeInserted'事件。

请注意,执行放置时,contentEditable元素会触发此元素,以便将其target属性设置为此元素。 您可以通过检查event.originalEvent.target属性来检索已移动的元素。

请注意,一旦完成删除并且插入了drop元素,就会触发此事件。

$('#editor').bind('DOMNodeInserted', function(event){
      if(event.originalEvent && event.originalEvent.target){
        var target = $(event.originalEvent.target);
        //now you can check what has been moved
      }
});

答案 1 :(得分: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>