互联网上有许多WYSIWYG编辑器,但我还没有找到一种实现某种形式的拖放实现的编辑器。
创建一个自己的编辑器很容易,但我希望用户能够从可编辑区域外拖动元素(即标记),并将它们放在可编辑区域内选择的位置。
在可编辑元素的特定位置注入html很容易,但是当用户在可编辑区域中的某个元素上拖动DIV时,如何确定插入符应该位于何处。为了更好地说明我要解释的内容,请参阅以下方案。
可编辑区域(编辑模式下的IFRAME或其contentEditable属性设置为true的DIV)已包含以下文本:
“亲爱的,请注意......”
用户现在从可编辑区域上的元素列表中拖动表示某个标记的元素,将光标移动到文本上,直到插入符号出现在文本中的逗号(,)之前,如上所示。当用户在该位置释放鼠标按钮时,将注入HTML,这可能导致如下所示:
“亲爱的{UserFirstName},请注意......”。
我不知道是否有人做过类似的事情,或者至少知道如何使用JavaScript来做这件事。
非常感谢任何帮助。
答案 0 :(得分:6)
以下是解决可编辑元素上自定义拖动元素问题的方法。最大的问题是当鼠标悬停在可编辑元素上时,无法确定鼠标光标的文本偏移量。我曾尝试伪造鼠标单击以将插入符号设置在所需位置,但这不起作用。即使它确实如此,人们也不会在拖动时直观地看到插入符号的位置,而只会看到产生的掉落。
由于可以将鼠标悬停事件绑定到元素而不是文本节点,因此可以将可编辑元素设置为暂时不可编辑。查找所有元素并将每个文本节点包装在一个范围中,以便不破坏文本流。应为每个范围指定一个类名,以便我们再次找到它们。
在包装之后,应该再次找到所有包装的文本节点,并用另一个带有可以再次找到它们的类名的span来包装每个字符。
使用事件委托可以向主可编辑元素添加一个事件,该元素将一个样式应用于将显示插入符号的每个字符跨度,一个闪烁的GIF图像作为背景。
同样,使用事件委托,应该为每个字符添加鼠标向上事件(drop事件)的事件。现在可以使用其父级(包装文本节点)中的字符跨度位置(偏移量)来确定偏移量。现在可以撤消所有包装,保持对计算的偏移的引用,同时撤消包装,保留对适用的文本节点的引用。
使用范围&浏览器的选择对象,现在可以使用计算的偏移量将选择设置为适用的文本节点,并在新设置的选择(插入位置),中提琴上注入所需的HTML!
下面是一个使用jQuery的代码片段,它将找到文本节点,包装它们:
editElement.find("*:not(.text-node)").contents().filter(function(){
return this.nodeType != 1;
}).wrap("<span class=\"text-node\"/>");
要查找每个文本节点并包装每个字符,请使用:
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>");
});
撤消包装:
editElement.find(".text-node").each(function()
{
this.parentNode.replaceChild(document.createTextNode($(this).text()), this);
});
希望这种方法可以帮助那些有类似挑战的人
答案 1 :(得分:2)
如果我明白你在说什么,那么这只是基本的拖放。下面的解决方案应该接近FIREFOX的最佳答案。我确信IE有不同的功能。转到http://www.html5rocks.com/en/tutorials/dnd/basics/获取更多帮助。
设置要拖动的对象的“draggable”属性,并将对象的“ondragstart”方法设置为“dragStartHandler”或任何函数调用。
// 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;
}
答案 2 :(得分:1)
目前正在开发一个HTML5 API来执行此操作,但不幸的是IE不支持它。编辑:显然IE实际上支持拖放,但我不是很熟悉如何有用。尝试Googling“IE拖放”。
尝试查看这些网站: