【问题标题】:Rangy for subdivided contenteditable divRangy 用于细分内容可编辑的 div
【发布时间】:2014-03-07 06:09:40
【问题描述】:

所以,我正在玩 (AWESOME) Rangy 文本选择包。我正在使用contenteditable=true 编辑span 内的文本,目标是拥有一个允许对每个字符进行单独样式设置的文本输入元素。让我强调最后一点——每个角色都应该在其自己的范围内。如果我不需要保留从一个按键到下一个按键的样式,这很好用——我只是做类似

var newHTML = field.innerText.split('').map(function(c){
    return ('<span class="letter">'+c+'</span>');
}).join('');
$(field).empty().append(newHTML);

并使用 Rangy 的 (1.3) saveCharacterRange() 函数恢复选择,一切都很好。

当我已经设置了其中一些跨度的样式时,问题就出现了,我删除了一个,用新文本替换它。我希望新插入的文本没有样式,而是插入到前面的(或后面的,如果选择在开头)范围中。我试图通过在focusNode之后(或之前)显式折叠选择区域来解决此问题,但它似乎不允许endContainer(或startContainer)成为文本节点以外的任何东西......我' 甚至验证我可以创建 一个文本范围,它可以在我想要的位置折叠,但选择对象的setSingleRange() 似乎在文本节点周围折叠回来。

我尝试插入一个新节点并将选择完全放在其中,确实在调用insertNode()之前新节点中有内容时起作用,但我显然不能插入额外的每个字符之间的内容...

这是一个fiddle,展示了我在说什么。感谢您的帮助!

【问题讨论】:

    标签: javascript html selection contenteditable rangy


    【解决方案1】:

    我认为您遇到了一个常见问题:浏览器(尤其是 WebKit)对文档中允许选择和插入符号的位置有特定的想法。这是我最近对这个问题的回答:

    https://stackoverflow.com/a/21591165/96100

    【讨论】:

    • 是的,这似乎是同一个问题。我玩弄了这个解决方案,但决定使用 jQuery 创建一个新跨度并将其插入到焦点节点的父元素之后。这还有其他问题,我开始认为我应该回到空跨度解决方案......我现在最大的问题是找到一个可以很好地输入装饰字符的解决方案,即é或中文输入。跨度>
    • 我试着听从你那篇文章的建议,它极大地提高了我的代码的简洁性和性能,但我还是有点迷茫。也许您可以利用您的专业知识来弄清楚我缺少什么?我在下面编辑了我的答案,以反映我目前的尝试状态。
    【解决方案2】:

    也许有人可以对此进行扩展,但我认为save/restoreCharacterRanges() 是解决此问题的关键。我已经让它工作了(假设您的选择区域已折叠)in this fiddle,虽然不是我想要的方式 - 这种方法(删除刚刚添加的内容并移动到新的跨度)会导致 keyup 和 keydown 之间闪烁.我真的希望能够将光标(在 keydown 上)移动到一个新的跨度,这对用户来说似乎是无缝的......

    ... 和here's a fiddle 适用于长选择,但不能粘贴...

    更新

    我已经切换到“插入&lt;span&gt;&amp;#8024;&lt;/span&gt; 并将选择区域移入其中”的方法,这似乎工作得很好,直到我开始尝试不同的浏览器。每个浏览器的行为完全不同! Chrome 在需要时正确地将光标移动到“空白”范围内,但随后会删除重音; Firefox 完美处理重音字符,但在删除新跨度之后的字符后无法移动到新跨度; Safari 显示重音标记 然后 移动到新的跨度中,使重音标记成为孤立的……当删除一个跟在新的一个!此外,似乎不同的浏览器在按下修饰键时报告了不同的键码。这是一个失败的原因吗?我错过了什么吗?这是fiddle with the new code

    【讨论】:

    • 欢迎来到 contenteditable 的混乱(ce 从这里开始)。您越希望ce某种 方式行事,您将遇到的障碍就越多。您已经发现浏览器在处理ce 时表现不同。对于我自己的project,我不得不编写大量代码来掩盖差异(而且可能还有一些我仍然遗漏的案例)。对输入法的支持(输入中文或重音字符)增加了一个全新的复杂程度。
    • 是的,我开始看到了。你和compositionstart/end/update一起工作过吗?
    • 是的。在this code 中搜索作曲事件名称。我现在使用的技术是让&lt;input&gt; 元素接收我关心的关键事件(包括合成),然后自己将数据插入可编辑文档中。如果您对插入符号的移动感到好奇,请查看nextCaretPositionprevCaretPositionhere。我提到的第一个文件中也有运动代码,但它是高度特定于项目的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-07-21
    • 2010-10-06
    • 2023-03-07
    • 2020-12-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多