js contenteditable-防止写入新插入的元素 [英] js contenteditable - prevent from writing into newly inserted element
问题描述
我正在研究一种简单的语法荧光笔,该荧光笔将带有dom元素的文本替换为类。
I'm working on a simply syntax highlighter that replaces text with dom elements with classes.
说,我有
<div contenteditable="true">
Some text. | And some other text.
</div>
,光标位于|管道
//如果用户键入 foo
<div contenteditable="true">
Some text. foo| And some other text.
</div>
//然后替换它,然后在插入的元素之后设置选择
// and I replace it, then set the selection after the inserted element
<div contenteditable="true">
Some text. <span class="highlight-foo">foo</span>| And some other text.
</div>
但是,如果键入,则输入跨度。无论如何。
but if you type, you type into the span..no matter what.
//类型栏
<div contenteditable="true">
Some text. <span class="highlight-foo">foobar|</span> And some other text.
</div>
我不想要那样,但是在新插入的内容之后我无法立即设置选择元件。
and I don't want that, but I can't set the selection right after the newly inserted element.
<div contenteditable="true">
Some text. <span class="highlight-foo">foo</span>bar| And some other text.
</div>
这是执行突出显示和替换的js。
here's the js that does the highlighting and replacing..
...
// 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..
如何解决?噢,我在这里读了很多东西,甚至在这里看了很多问题,但对这个特殊问题一无所获。
How to solve that? oO I've read a lot on it even looked a fair amount of questions on here, but nothing regarding this particular problem.
推荐答案
我假设您正在WebKit中对此进行测试。 WebKit的插入符号处理可防止您将插入符号放置在文本节点的开头: https:// bugs.webkit.org/show_bug.cgi?id=23189 。在Firefox中,您的代码应该没问题。
I assume you're testing this in WebKit. WebKit's caret handling prevents you from placing the caret at the start of a text node: https://bugs.webkit.org/show_bug.cgi?id=23189. In Firefox your code should be fine.
所有解决方法都很可怕。一种是插入一个零宽度的空格(例如 \u200B
)并选择它,但是您需要添加特殊的代码来处理箭头键并删除零号。宽度空格。
The workarounds are all horrible. One is to insert a zero-width space (such as \u200B
) and select it, but then you have add special code to handle arrow keys and code to remove the zero-width spaces.
更新
另一种解决方法是使用以下事实: WebKit对于链接有一种特殊情况,它迫使插入符在链接之后移动:
Another workaround is to use the fact that WebKit has a special case for links where it forces the caret to go after the link:
所以您可以做的,虽然不愉快但可行的,是使用< span>
,当您希望插入符号进入突出显示的元素内,然后将其更改为链接时。
So what you could do, which is unpleasant but doable, is to use a <span>
when you want the caret to go inside the highlighted element and change it into a link otherwise.
这篇关于js contenteditable-防止写入新插入的元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!