简体   繁体   English

通过jscript编辑内容后,保持插入位置满足

[英]Keep caret position in contenteditable after editing the content via jscript

I've got a contenteditable div which's content is being edited via javascript after each textchange( textchange.js ) like adding html tags(only span-tags for changing the color of some words) and adding or removing some whitespaces here and there, but my problem is since the content is being changed while the user is editing it, the caret changes its position after every keypress, which makes it nearly impossible to write a single word. 我有一个contenteditable div,其内容是在每个textchange( textchange.js )之后通过javascript编辑的,比如添加html标签(只有span-tags用于更改某些单词的颜色)以及在这里和那里添加或删除一些空格,但是我的问题是因为在用户编辑内容时正在更改内容,插入符号在每次按键后都会改变其位置,这使得几乎不可能写出单个单词。 I'm at the moment searching for a way to prevent this jumping around, I've already thought of adding a special char which wouldn't be used anyway as a kind of marker at the position of the caret before editing it, removing it when finished and putting the caret back to this position, but since I'm using regex a lot(currently about 25 times after each textchange) this special character would ruin nearly every single one of them and I would have to add something like \\x40? 我正在寻找一种防止这种跳跃的方法,我已经考虑过添加一个特殊的字符串,在编辑它之前不会被用作插入符号位置的一种标记,将其删除当完成并将插入符号放回到这个位置时,但由于我正在使用正则表达式(目前每次文本更改后大约25次),这个特殊字符几乎会破坏它们中的每一个,我将不得不添加类似\\x40? every where, which would not look nice and clear at all: 每个地方,根本不会看起来漂亮和清晰:

/\s<span class="b0">hello\sworld</span>/g

to: 至:

/\s\x40?<span class="b0">\x40?h\x40?e\x40?l\x40?l\x40?o\x40?\s\x40?w\x40?o\x40?r\x40?l\x40?d\x40?</span>/g

I don't know if it helps but here is an example on how the content is changed(after each keypress): 我不知道它是否有帮助,但这里有一个关于如何更改内容的示例(在每次按键之后):

foo +++   <span class="c3">bar</span> - baz -<span class="c0">qux</span>

to: 至:

<span class="c1">foo</span> + <span class="c3">bar</span> - <span class="c1">baz</span> * <span class="c0">qux</span>

I'd be grateful for every advice, tip or hint on how to solve this problem, or a better way to do this marker-thing. 对于如何解决这个问题的每一个建议,提示或提示,或者更好的方法来做这个标记,我将不胜感激。

Thank you :) 谢谢 :)

Probably this is not the best solution, but I created 2 divs, one to display the text and other to edit it, the second one above the first one and with some level of transparency. 可能这不是最好的解决方案,但我创建了2个div,一个用于显示文本,另一个用于编辑它,第二个用于显示第一个div,并且具有一定程度的透明度。

Like this: 像这样:

<div style="position: absolute; left: 48px; top: 16px;" unselectable="on" onselectstart="return false">
    <code id="code_show">Type here.</code>
</div>
<div style="position: absolute; left: 48px; top: 16px;">
    <span style="opacity:0.33"><code id="code_area" contenteditable="true" onkeyup="colorize();">Type here.</code></span>
</div>

The onselectstart="return false" and the unselectable="on" ensure that the first one is not selectable. onselectstart="return false"unselectable="on"确保第一个不可选。 The onkeyup="colorize();" onkeyup="colorize();" ensures that the javascript function colorize is called everytime that the user presses a key to edit the text. 确保每次用户按下键来编辑文本时调用javascript函数colorize

So you have to define it to update the contents of code_show to match the ones in code_area but with colors. 所以,你必须把它定义更新的内容code_show以匹配那些code_area但颜色。

For instance, this code paints every word RED in red color: 例如,此代码以红色绘制每个单词RED:

<script>
function colorize(){
    var code_area= document.getElementById('code_area');
    var code_show= document.getElementById('code_show');

    var inner= code_area.innerHTML;
    inner= inner.replace(/RED/g,"<span style=\"color: red\">RED</span>");
    code_show.innerHTML= inner;
}
</script>

You could create an abstraction that would add special characters to otherwise readable regexes. 您可以创建一个抽象,将特殊字符添加到其他可读的正则表达式。 It's simple and presumably requires minimal changes to your current code. 它很简单,可能需要对当前代码进行最小的更改。

There might be a more elegant solution though. 可能会有一个更优雅的解决方案。 If you never replace text that has a caret in a middle of it - as in repl|aced - you could split the original string into two and apply the filter on both parts. 如果你永远不会替换在其中间有插入符号的文本 - 如在repl|aced - 你可以将原始字符串拆分为两个并在两个部分上应用过滤器。 The caret position remains at the division, that is at length of the first gist. 插入位置仍然在分区,这是第一个要点的长度。

If you do however need to replace even at caret position, you could start with the split anyway. 如果你确实需要更换甚至在插入位置,你仍然可以从拆分开始。 After that, run the filters again, one by one. 之后,再次逐个运行过滤器。 If the filter matched, move caret to a predetermined relative position - say to replaced ++|+ (pipe denoting the caret) with ×× . 如果过滤器匹配,则将插入符号移动到预定的相对位置 - 比如用××替换++|+ (表示插入符号的管道)。 You could even let it be, which would result in ××| 你甚至可以让它,这将导致××| . Or have a hardcoded relative caret move for each filter, which is great if you do code replacements, because you can move the caret to proper location (say you replace <|i></i> with <em>|<em> ; notice the caret conveniently moved to where the user would probably want it). 或者为每个过滤器设置一个硬编码的相对插入符号移动,这对于代码替换很有用,因为您可以将插入符移动到正确的位置(比如用<em>|<em>替换<|i></i> <em>|<em> ;注意插入符号方便地移动到用户可能想要的位置)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM