admin管理员组文章数量:1405621
I am trying to replace any instances of /any thing in here/
with <b>/any thing in here/</b>
on the fly, as changes are made in a contenteditable div.
My current implementation works, but at every keypress the caret is moved to the beginning of div making the implementation unusable. Is there some way to keep the caret position while replacing the div's contents?
$('.writer').on('keyup', function(e) {
$(this).html($(this).html().replace(/\/(.*)\//g, '<b>\/$1\/<\/b>'));
});
I am trying to replace any instances of /any thing in here/
with <b>/any thing in here/</b>
on the fly, as changes are made in a contenteditable div.
My current implementation works, but at every keypress the caret is moved to the beginning of div making the implementation unusable. Is there some way to keep the caret position while replacing the div's contents?
$('.writer').on('keyup', function(e) {
$(this).html($(this).html().replace(/\/(.*)\//g, '<b>\/$1\/<\/b>'));
});
Share
Improve this question
edited Oct 10, 2018 at 6:33
Cœur
38.8k25 gold badges205 silver badges277 bronze badges
asked Jul 19, 2014 at 21:42
slyvslyv
8381 gold badge10 silver badges18 bronze badges
5
-
Is there a reason you have to use a
div
withcontenteditable
instead of atextarea
or something similar? – royhowie Commented Jul 19, 2014 at 21:47 - @Luxelin: I'd like to render html within the div, and as far as I am aware, html can't be rendered inside a textarea. – slyv Commented Jul 19, 2014 at 21:49
- Even if you were to use a textarea I'm sure the caret would still move around. – Lee Taylor Commented Jul 19, 2014 at 21:53
- 2 This question may be of use for you, regarding setting the caret position. – royhowie Commented Jul 19, 2014 at 21:54
- I've answered a very similar question recently: stackoverflow./a/24687874/96100 – Tim Down Commented Jul 20, 2014 at 16:33
1 Answer
Reset to default 6
$('#writer').on('keyup', function(e) {
var range = window.getSelection().getRangeAt(0);
var end_node = range.endContainer;
var end = range.endOffset;
if(end_node != this){
var text_nodes = get_text_nodes_in(this);
for (var i = 0; i < text_nodes.length; ++i) {
if(text_nodes[i] == end_node){
break;
}
end += text_nodes[i].length;
}
}
var html = $(this).html();
if(/\ $/.test(html) && $(this).text().length == end){
end = end - 1;
set_range(end,end,this);
return;
}
var filter = html.replace(/(<b>)?\/([^<\/]*)(<\/b>)?/g, '\/$2');
console.log(filter);
filter = filter.replace(/(<b>)?([^<\/]*)\/(<\/b>)?/g, '$2\/');
console.log(filter);
filter = filter.replace(/(<b>)?\/([^<\/]*)\/(<\/b>)?/g, '<b>\/$2\/<\/b>');
console.log(filter);
if(!/\ $/.test($(this).html())){
filter += ' ';
}
$(this).html(filter);
set_range(end,end,this);
});
$('#writer').on('mouseup', function(e) {
if(!/\ $/.test($(this).html())){
return;
}
var range = window.getSelection().getRangeAt(0);
var end = range.endOffset;
var end_node = range.endContainer;
if(end_node != this){
var text_nodes = get_text_nodes_in(this);
for (var i = 0; i < text_nodes.length; ++i) {
if(text_nodes[i] == end_node){
break;
}
end += text_nodes[i].length;
}
}
if($(this).text().length == end){
end = end - 1;
set_range(end,end,this);
}
});
function get_text_nodes_in(node) {
var text_nodes = [];
if (node.nodeType === 3) {
text_nodes.push(node);
} else {
var children = node.childNodes;
for (var i = 0, len = children.length; i < len; ++i) {
var text_node
text_nodes.push.apply(text_nodes, get_text_nodes_in(children[i]));
}
}
return text_nodes;
}
function set_range(start, end, element) {
var range = document.createRange();
range.selectNodeContents(element);
var text_nodes = get_text_nodes_in(element);
var foundStart = false;
var char_count = 0, end_char_count;
for (var i = 0, text_node; text_node = text_nodes[i++]; ) {
end_char_count = char_count + text_node.length;
if (!foundStart && start >= char_count && (start < end_char_count || (start === end_char_count && i < text_nodes.length))) {
range.setStart(text_node, start - char_count);
foundStart = true;
}
if (foundStart && end <= end_char_count) {
range.setEnd(text_node, end - char_count);
break;
}
char_count = end_char_count;
}
var selection = window.getSelection();
selection.removeAllRanges();
selection.addRange(range);
}
<script src="https://cdnjs.cloudflare./ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="writer" contenteditable style="width:300px;height:100px;border:1px solid #ccc;">/input some words here!/</div>
版权声明:本文标题:javascript - Modify text in a contenteditable div without resetting the caret (cursor) position - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744295907a2599339.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论