简体   繁体   中英

Drag and drop event in a contentEditable element

What event is fired when one drops something in a contentEditable element (after dragging)?

I'm talking about plain old drag and drop, NOT HTML5 drag and drop (where any element can be made draggable); the use case is simply:

  • there's a contentEditable div on the page, used as an editor
  • the user drags and drops some HTML from the current page or from another page, or from another browser's window (so there really isn't any concept of "source" object: the source can come from outside the browser)
  • I need to be notified that the content has been dropped into the contentEditable div so that I can act on it (clean it)

I could poll the div to see if anything's there that's not clean, but it's expensive and "ugly"; surely there's an event that fires when a drop occurs...?

I faced the same problem while writing a tinyMCE plugin. What I found the best way to track drag and drop of elements in a contentEditable zone is to listen to the 'DOMNodeInserted' event on the contentEditable element.

Note that this element is fired by the contentEditable element when the drop is performed so that its target property is set to this element. You can retrieve the moved element by checking the event.originalEvent.target property.

Be aware that this event is fired once the dropped is finished and that the drop element has been inserted.

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

Here is a workaround solution, just using the ondrop event. The ondrop event works, but the problem is that it fires before the content has changed. So the workaround is to use setTimeout with a little delay.

Here is the solution snippet you can test. When (after) you drop an image on the top div, the content of that div will be copied to the bottom div. Read the comment in the code, it gives more info on how you can handle the delay.

 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>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM