在contentEditable元素上拖放n-Drop

Nei*_*ilC 14 javascript drag-and-drop contenteditable

互联网上有许多WYSIWYG编辑器,但我还没有找到一种实现某种形式的拖放实现的编辑器.

创建一个自己的编辑器很容易,但我希望用户能够从可编辑区域外拖动元素(即标记),并将它们放在可编辑区域内选择的位置.

在可编辑元素的特定位置注入html很容易,但是当用户在可编辑区域中的某个元素上拖动DIV时,如何确定插入符应该在何处.为了更好地说明我要解释的内容,请参阅以下方案.

可编辑区域(编辑模式下的IFRAME或其contentEditable属性设置为true的DIV)已包含以下文本:

"亲爱的,请注意......"

用户现在在可编辑区域上拖动表示元素列表中某个标记的元素,将光标移动到文本上,直到插入符号出现在文本中的逗号(,)之前,如上所示.当用户在该位置释放鼠标按钮时,将注入HTML,这可能会导致如下所示:

"亲爱的{UserFirstName},请注意......".

我不知道是否有人做过类似的事情,或者至少知道如何使用JavaScript做这件事.

任何帮助将不胜感激.

Nei*_*ilC 6

这是我解决可编辑元素上自定义拖动元素问题的方法.最大的问题是当鼠标悬停在可编辑元素上时,无法确定鼠标光标的文本偏移量.我曾尝试伪造鼠标单击以将插入符号设置在所需位置,但这不起作用.即使它确实如此,人们也不会在拖动时直观地看到插入符号的位置,而只会看到产生的掉落.

由于可以将鼠标悬停事件绑定到元素而不是文本节点,因此可以将可编辑元素设置为暂时不可编辑.查找所有元素并将每个文本节点包装在一个范围中,以便不破坏文本流.应为每个范围指定一个类名,以便我们再次找到它们.

在包装之后,应该再次找到所有包装的文本节点,并用另一个带有可以再次找到它们的类名的跨度包装每个字符.

使用事件委托可以向主可编辑元素添加一个事件,该元素将一个样式应用于将显示插入符号的每个字符跨度,一个闪烁的GIF图像作为背景.

同样,使用事件委托,应该为每个字符添加鼠标添加事件(drop事件)的事件.现在可以使用其父级(包装文本节点)中的字符跨度位置(偏移量)来确定偏移量.现在可以撤消所有包装,保持对计算的偏移的引用,同时撤消包装保持对适用的文本节点的引用.

使用浏览器的范围和选择对象,现在可以使用计算的偏移量将选择设置为适用的文本节点,并在新设置的选择(插入位置)和中提琴中注入所需的HTML!

下面是一个使用jQuery的代码片段,它将找到文本节点,将它们包装起来:

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

要查找每个文本节点并包装每个字符,请使用:

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>");
});
Run Code Online (Sandbox Code Playgroud)

撤消包装:

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

希望这种方法可以帮助那些遇到类似挑战