js contenteditable - 防止写入新插入的元素

时间:2012-05-10 22:00:25

标签: javascript selection range contenteditable

我正在研究一种简单的语法高亮显示,用dom元素替换带有类的文本。

说,我有一个

<div contenteditable="true">
  Some text. | And some other text.
</div>

,光标位于|管道

//如果用户输入foo

<div contenteditable="true">
  Some text. foo| And some other text.
</div>

//我替换它,然后在插入的元素

之后设置选择
<div contenteditable="true">
  Some text. <span class="highlight-foo">foo</span>| And some other text.
</div>

但是如果你打字,你输入跨度......无论如何。

//键入栏

<div contenteditable="true">
  Some text. <span class="highlight-foo">foobar|</span> And some other text.
</div>

我不想这样,但我不能在新插入的元素之后立即设置选择。

<div contenteditable="true">
  Some text. <span class="highlight-foo">foo</span>bar| And some other text.
</div>

这是突出显示和替换的js ..

...
// chunk is the variable that holds foo, if we stick the the above example..
// select it
range.setStart(range.startContainer, range.startOffset-chunk.length);

// add it to the range
sel.addRange(range);

// replace it..then set the range to the textNode after the span
// because after the injection selection.anchorNode is the textNode inside the span..
// in chrome, however, this below sets the range correctly.
range.setStart(sel.anchorNode.parentNode.nextSibling, 0);

// and it's all good until now, but adding the range to the selection does nothing..
sel.removeAllRanges();
sel.addRange(range)

// the selection is still inside the span..

如何解决?我在这里看了很多,甚至在这里看了很多问题,但没有关于这个特殊问题。

1 个答案:

答案 0 :(得分:6)

我假设你在WebKit中测试它。 WebKit的插入处理阻止您将插入符号放在文本节点的开头:https://bugs.webkit.org/show_bug.cgi?id=23189。在Firefox中,您的代码应该没问题。

变通办法非常糟糕。一种是插入零宽度空间(例如\u200B)并选择它,但是你需要添加特殊代码来处理箭头键和代码以删除零宽度空间。

<强>更新

另一个解决方法是使用这样一个事实:WebKit有一个特殊的案例,用于强制插入符号链接的链接:

http://jsfiddle.net/RfMju/

因此,当您希望插入符号位于突出显示的元素内部并将其更改为链接时,您可以执行的操作是令人不快但可行的<span>