拖N - 下降
目前在互联网上提供大量的所见即所得的编辑器,但我还没有找到一个实现某种形式的拖放正下降落实。拖N - 下降
创建自己的编辑器很容易,但我希望用户能够从可编辑区域外部拖动元素(即令牌),并让它们在可编辑区域内的选定位置放置它。
在可编辑元素的特定位置很容易注入html,但是如何确定用户在可编辑区域中的某个元素上拖动DIV时插入符的位置。为了更好地说明我想要解释的内容,请参阅以下方案。
可编辑区域(无论是在编辑模式下的iframe或设置为true其CONTENTEDITABLE属性的DIV)已经包含了以下文字:
“亲爱的,请注意一下......”
现在,用户在可编辑区域上拖动一个元素列表中代表某个标记的元素,将光标移动到文本上方,直到脱字符出现在文本中的逗号(,)之前,如上所示。当用户在该位置释放鼠标按键,HTML将被注入这可能会导致这样的事情:
“亲爱的{} USERFIRSTNAME,请采取笔记...”。
我不知道是否有人曾经做过的一个将如何去这样做使用JavaScript任何与此类似,或至少知道了。
任何帮助将不胜感激。
这里是我的方法来解决这个问题在可编辑元素上的自定义拖动元素。最大的问题是,当鼠标悬停在可编辑元素上时,无法确定鼠标光标的文本偏移量。我试图伪造鼠标点击设置在所需的位置插入符号,但没有奏效。即使这样做,人们在拖曳时也不会在视觉上看到脱字符号的位置,但只会导致下降。
由于一个可以结合鼠标悬停事件的元件,而文本的节点,一个可以设置编辑元素是暂时不可编辑。查找所有元素并将每个文本节点包装在一个范围内,以便不中断文本流。每个跨度应该有一个类名,以便我们可以再次找到它们。
包装后,应再次找到所有的换行文本节点,并用一个类名,人们可以再次找到他们另一个跨度包装的每个字符。
使用事件委托可以将一个事件添加到主要可编辑元素,该元素将对每个字符跨度应用样式,以显示插入符号(即闪烁的GIF图像作为背景)。
再次,使用事件委托,应该为每个字符上的鼠标事件(drop事件)添加一个事件。现在可以使用其父级(包装文本节点)内的字符跨度位置(偏移量)来确定偏移量。现在可以撤销所有包装,保留对计算出的偏移量的引用,同时撤消包装以保留对适用文本节点的引用。
使用范围&浏览器的选择对象,现在可以使用计算出的偏移量来设置选择到适用的文本节点,并在新设置的选择(插入位置)et viola注入所需的HTML!
这里紧跟使用jQuery一个片段,就会发现textnodes,他们包装:
editElement.find("*:not(.text-node)").contents().filter(function(){
return this.nodeType != 1;
}).wrap("<span class=\"text-node\"/>");
要找到每个文本节点和包装每个字符,请使用:
要撤消包装:
editElement.find(".text-node").each(function()
{
this.parentNode.replaceChild(document.createTextNode($(this).text()), this);
});
希望这种方法可以帮助那些有类似挑战的人
目前的HTML5 API正在开发要做到这一点,
可惜IE不支持它。
编辑:显然,IE实际上支持拖放,但我不是很熟悉它是如何工作的。尝试Googling“IE拖放”。
尝试寻找这些网站:
我的一位同事找到了解决方案,这是我要求提出的问题。我会很快在这里发布解决方案 – Raybiez 2010-07-01 11:27:58
唉,他的解决方案并不适用。狩猎又回来了...... grrr – Raybiez 2011-07-20 13:59:03
@Raybiez也许你可以编辑你的问题来添加不起作用的解决方案?这也会将这个问题带回头版的副作用。 – Na7coldwater 2011-07-21 22:01:59
如果我明白你在说什么,那么这只是基本的拖放。下面的解决方案应该接近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;
}
感谢您的回应,但这依赖于HTML5,并且应用程序必须支持旧浏览器。对于不支持传统浏览器的新更新应用程序,此方法将最适合。 – Raybiez 2014-04-11 12:37:42
它可能不是需要申请上的字符跨度如上所述,可以使用可放开事件的原始事件属性,以确定是否在实际上可拖动已在角色跨度下降委派mouseUp事件。只是供参考.... – Raybiez 2011-08-17 14:03:53