Reputation: 93
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.
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?
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 :)
Upvotes: 7
Views: 996
Reputation: 33
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.
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. The onkeyup="colorize();"
ensures that the javascript function colorize
is called everytime that the user presses a key to edit the text.
So you have to define it to update the contents of code_show
to match the ones in code_area
but with colors.
For instance, this code paints every word RED in red color:
<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>
Upvotes: 1
Reputation: 7941
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. 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).
Upvotes: 0