拖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); 
}); 

希望这种方法可以帮助那些有类似挑战的人

+1

它可能不是需要申请上的字符跨度如上所述,可以使用可放开事件的原始事件属性,以确定是否在实际上可拖动已在角色跨度下降委派mouseUp事件。只是供参考.... – Raybiez 2011-08-17 14:03:53

目前的HTML5 API正在开发要做到这一点, 可惜IE不支持它。 编辑:显然,IE实际上支持拖放,但我不是很熟悉它是如何工作的。尝试Googling“IE拖放”。

尝试寻找这些网站:

+0

我的一位同事找到了解决方案,这是我要求提出的问题。我会很快在这里发布解决方案 – Raybiez 2010-07-01 11:27:58

+0

唉,他的解决方案并不适用。狩猎又回来了...... grrr – Raybiez 2011-07-20 13:59:03

+0

@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; 
} 
+0

感谢您的回应,但这依赖于HTML5,并且应用程序必须支持旧浏览器。对于不支持传统浏览器的新更新应用程序,此方法将最适合。 – Raybiez 2014-04-11 12:37:42