草庐IT

javascript - 在 contentEditable 元素上拖放

coder 2024-05-09 原文

互联网上有许多所见即所得的编辑器,但我还没有找到一个实现某种形式的拖放操作的编辑器。

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

在可编辑元素的特定位置插入 html 很容易,但是当用户将 DIV 拖到可编辑区域中的某个元素上时,如何确定插入符号的位置。为了更好地说明我要解释的内容,请参阅以下场景。

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

“亲爱的,请注意……”

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

“亲爱的{UserFirstName},请注意...”。

我不知道是否有人曾经做过类似的事情,或者至少知道如何使用 JavaScript 来做到这一点。

任何帮助将不胜感激。

最佳答案

这是我解决可编辑元素上的自定义拖动元素问题的方法。最大的问题是当鼠标悬停在可编辑元素上时无法确定鼠标光标的文本偏移量。我曾尝试假装单击鼠标以将插入符号设置在所需位置,但这没有用。即使这样做了,人们也不会在拖动时直观地看到插入符号的位置,而只能看到产生的拖放。

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

包装后,应该再次找到所有包装的文本节点,并用另一个带有类名的范围包装每个字符,以便再次找到它们。

使用事件委托(delegate),可以向主要的可编辑元素添加一个事件,该事件将一种样式应用于将显示插入符号的每个字符范围,一个闪烁的 GIF 图像作为背景。

同样,使用事件委托(delegate),应该为每个 Angular 色的鼠标松开事件(放下事件)添加一个事件。现在可以使用字符跨度在其父级(环绕的文本节点)中的位置(偏移量)来确定偏移量。现在可以撤消所有换行,保留对计算偏移量的引用,并在撤消换行时保留对适用文本节点的引用。

使用浏览器的范围和选择对象,现在可以使用计算的偏移量将选择设置为适用的文本节点,并在新设置的选择(插入位置)处注入(inject)所需的 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);
});

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

关于javascript - 在 contentEditable 元素上拖放,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3006623/

有关javascript - 在 contentEditable 元素上拖放的更多相关文章

  1. ruby - 在哈希的键数组中追加元素 - 2

    查看我的Ruby代码:h=Hash.new([])h[0]=:word1h[1]=h[1]输出是:Hash={0=>:word1,1=>[:word2,:word3],2=>[:word2,:word3]}我希望有Hash={0=>:word1,1=>[:word2],2=>[:word3]}为什么要附加第二个哈希元素(数组)?如何将新数组元素附加到第三个哈希元素? 最佳答案 如果您提供单个值作为Hash.new的参数(例如Hash.new([]),完全相同的对象将用作每个缺失键的默认值。这就是您所拥有的,那是你不想要的。您可以改用

  2. 「Python|Selenium|场景案例」如何定位iframe中的元素? - 2

    本文主要介绍在使用Selenium进行自动化测试或者任务时,对于使用了iframe的页面,如何定位iframe中的元素文章目录场景描述解决方案具体代码场景描述当我们在使用Selenium进行自动化测试的时候,可能会遇到一些界面或者窗体是使用HTML的iframe标签进行承载的。对于iframe中的标签,如果直接查找是无法找到的,会抛出没有找到元素的异常。比如近在咫尺的例子就是,CSDN的登录窗体就是使用的iframe,大家可以尝试通过F12开发者模式查看到的tag_name,class_name,id或者xpath来定位中的页面元素,会抛出NoSuchElementException异常。解决

  3. ruby - Hanami link_to 助手只呈现最后一个元素 - 2

    我是HanamiWorld的新人。我已经写了这段代码:moduleWeb::Views::HomeclassIndexincludeWeb::ViewincludeHanami::Helpers::HtmlHelperdeftitlehtml.headerdoh1'Testsearchengine',id:'title'hrdiv(id:'test')dolink_to('Home',"/",class:'mnu_orizontal')link_to('About',"/",class:'mnu_orizontal')endendendendend我在模板上调用了title方法。htm

  4. ruby - 将n维数组的每个元素乘以Ruby中的数字 - 2

    在Ruby中,是否有一种简单的方法可以将n维数组中的每个元素乘以一个数字?这样:[1,2,3,4,5].multiplied_by2==[2,4,6,8,10]和[[1,2,3],[1,2,3]].multiplied_by2==[[2,4,6],[2,4,6]]?(很明显,我编写了multiplied_by函数以区别于*,它似乎连接了数组的多个副本,不幸的是这不是我需要的)。谢谢! 最佳答案 它的长格式等价物是:[1,2,3,4,5].collect{|n|n*2}其实并没有那么复杂。你总是可以使你的multiply_by方法:c

  5. ruby-on-rails - 使用 javascript 更改数据方法不会更改 ajax 调用用户的什么方法? - 2

    我遇到了一个非常奇怪的问题,我很难解决。在我看来,我有一个与data-remote="true"和data-method="delete"的链接。当我单击该链接时,我可以看到对我的Rails服务器的DELETE请求。返回的JS代码会更改此链接的属性,其中包括href和data-method。再次单击此链接后,我的服务器收到了对新href的请求,但使用的是旧的data-method,即使我已将其从DELETE到POST(它仍然发送一个DELETE请求)。但是,如果我刷新页面,HTML与"new"HTML相同(随返回的JS发生变化),但它实际上发送了正确的请求类型。这就是这个问题令我困惑的

  6. arrays - 计算数组中的匹配元素 - 2

    给定两个大小相等的数组,如何找到不考虑位置的匹配元素的数量?例如:[0,0,5]和[0,5,5]将返回2的匹配项,因为有一个0和一个5共同;[1,0,0,3]和[0,0,1,4]将返回3的匹配项,因为0有两场,1有一场;[1,2,2,3]和[1,2,3,4]将返回3的匹配项。我尝试了很多想法,但它们都变得相当粗糙和令人费解。我猜想有一些不错的Ruby习惯用法,或者可能是一个正则表达式,可以很好地回答这个解决方案。 最佳答案 您可以使用count完成它:a.count{|e|index=b.index(e)andb.delete_at

  7. ruby - 使用 Nokogiri 和 Ruby 命名元素 "text" - 2

    我在尝试使用Nokogiri构建XML文档时遇到了一个小问题。我想将我的元素之一称为“文本”(请参阅​​下面粘贴代码的最底部)。通常,要创建一个新元素,我会执行类似以下的操作xml.text--但它似乎是.text是Nokogiri已经用来做其他事情的方法。因此,当我写这行时xml.textNokogiri没有创建名为的新元素但只是写了意味着成为元素内容的文本。我怎样才能让Nokogiri实际制作一个名为的元素??builder=Nokogiri::XML::Builder.newdo|xml|xml.TEI("xmlns"=>"http://www.tei-c.org/ns/1.0"

  8. ruby - 在 factory_girl 中有没有办法获取 attributes_for 并为同一个实例元素创建? - 2

    如果我想使用“create”构建策略创建和实例,然后想使用“attributes_for”构建策略进行验证,是否可以这样做?如果我在工厂中使用序列?在Machinistgem中有可能吗? 最佳答案 不太确定我是否完全理解。而且我不是机械师的用户。但听起来您只是想做这样的事情。@attributes=FactoryGirl.attributes_for(:my_object)my_object=MyObject.create(@attributes)my_object.some_property.should==@attributes

  9. ruby - 数组数组中的唯一元素 - 2

    我想通过内部数组中的第一个元素从数组数组中找到唯一元素。例如a=[[1,2],[2,3],[1,5]我想要类似的东西[[1,2],[2,3]] 最佳答案 uniq方法需要一个block:uniq_a=a.uniq(&:first)或者如果您想就地进行:a.uniq!(&:first)例如:>>a=[[1,2],[2,3],[1,5]]=>[[1,2],[2,3],[1,5]]>>a.uniq(&:first)=>[[1,2],[2,3]]>>a=>[[1,2],[2,3],[1,5]]或者>>a=[[1,2],[2,3],[1,5]

  10. arrays - 在一行中选择数组的第一个和最后一个元素 - 2

    我的任务是从数组中选择最高和最低的数字。我想我很清楚我想做什么,但只是努力以正确的格式访问信息以满足通过标准。defhigh_and_low(numbers)array=numbers.split("").map!{|x|x.to_i}array.sort!{|a,b|ba}putsarray[0,-1]end数字可能看起来像"80917234100",要通过,我需要输出"9234"。我正在尝试putsarray.first.last,但一直无法弄明白。 最佳答案 有Array#minmax完全满足您需要的方法:array=[80,

随机推荐