js contenteditable-防止写入新插入的元素 [英] js contenteditable - prevent from writing into newly inserted element

查看:397
本文介绍了js contenteditable-防止写入新插入的元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在研究一种简单的语法荧光笔,该荧光笔将带有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:

http://jsfiddle.net/RfMju/

所以您可以做的,虽然不愉快但可行的,是使用< 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆