Drag-n-Drop on contentEditable elements

前端 未结 3 1132
星月不相逢
星月不相逢 2020-12-15 08:38

There are numerous WYSIWYG editors available on the internet, but I\'m yet to find one that implements some form of drag-n-drop implementation.

It is easy to create

相关标签:
3条回答
  • 2020-12-15 09:30

    Here is my approach to solving the issue of custom drag elements on editable elements. The big issue is that one cannot determine the text offset of the mouse cursor when hovering over the editable element. I have tried faking a mouse click to set the caret at the desired position but that did not work. Even if it did, one would not visually see the placement of the caret while dragging, but only the resulting drop.

    Since one can bind mouse-over events to elements and not text-nodes, one can set the editable element to be temporarily un-editable. Find all elements and wrap each text-node in a span as to not breaking the flow of the text. Each span should be given a classname so we can find them again.

    After the wrapping, one should again find all the wrapped text-nodes and wrap each character with another span with a classname that one can find them again.

    Using event delegation one can add an event to the main editable element that will apply a style to each character span that will display the caret, a blinking GIF image as a background.

    Again, using event delegation, one should add an event for the mouse-up event (drop event) on each character. One can now determine the offset using the character span's position (offset) within its parent (wrapped text-node). One can now undo all the wrapping, keeping a reference to the calculated offset and while undoing the wrapping keeping a reference to the applicable text-node.

    Using the range & selection objects of the browser, one can now set the selection using the calculated offset to the applicable text-node and inject the required HTML at the newly set selection (caret position), et viola!

    Here follows a snippet using jQuery that will find textnodes, wrap them:

    editElement.find("*:not(.text-node)").contents().filter(function(){ 
        return this.nodeType != 1;
    }).wrap("<span class=\"text-node\"/>");
    

    To find each text-node and wrap each character, use:

    editElement.find(".text-node").each(function()
    {
        var textnode = $(this), text = textnode.text(), result = [];
    
        for (var i = 0; i < text.length; i++) result.push(text.substr(i, 1));
    
        textnode.html("<span class=\"char\">" 
            + result.join("</span><span class=\"char\">") + "</span>");
    });
    

    To undo the wrapping:

    editElement.find(".text-node").each(function()
    {
        this.parentNode.replaceChild(document.createTextNode($(this).text()), this);
    });
    

    Hope this approach helps those having similar challenges

    0 讨论(0)
  • 2020-12-15 09:32

    If I understand what you're saying, then this is just basic drag and drop. The solution below should be close to the best answer for FIREFOX. I'm sure there are different functions for IE. Go to http://www.html5rocks.com/en/tutorials/dnd/basics/ for more help.

    Set the "draggable" attribute of the object you want to drag, and set the object's "ondragstart" method to "dragStartHandler" or whatever your function is called.

    // You can set this to 'text/plain' if you don't want to insert HTML content
    var internalDNDType = 'text/html';
    
    function dragStartHandler(event) {
      // This is whatever html data you want to insert.
      var textContent = "<b>"+userFirstName+"</b>";
    
      event.dataTransfer.setData(internalDNDType, textContent);
      event.dataTransfer.effectAllowed = 'copy';
    }
    
    function dragEnterHandler(event)
    {
      event.preventDefault();
      return false;
    }
    
    function dragOverHandler(event)
    {
      event.preventDefault();
      return false;
    }
    
    function dropHandler(event) {
      event.preventDefault();
      event.stopPropogation();
      return false;
    }
    
    0 讨论(0)
  • 2020-12-15 09:40

    Currently an HTML5 API is being developed to do this, but unfortunately IE doesn't support it. Edit: Apparently IE actually does support drag and drop, but I'm not very familiar with how it works. Try Googling "IE drag and drop".

    Try looking at these sites:

    • https://developer.mozilla.org/en/DragDrop/Drag_and_Drop
    • http://html5doctor.com/native-drag-and-drop/
    • http://www.thebuzzmedia.com/html5-drag-and-drop-and-file-api-tutorial/
    • http://www.webreference.com/programming/javascript/dragdropie/ (Drag and Drop in IE)
    0 讨论(0)
提交回复
热议问题