I've been searching through a lot of Range and Selection related questions (mostly answered by @tim-down), but I can't quite get what I need, although I come close.
I want to search the currently focused text node for the word foo
. If I find it - replace it with bar
and set the caret position at the end of the replaced word. For example:
"Lorem ipsum dolor foo amet, consectetur adipiscing elit."
Turns into:
"Lorem ipsum dolor bar amet, consectetur adipiscing elit."
// -------------------^--- caret position
What I currently have works only halfway - it removes the text, but doesn't add anything. I'm not sure it's the best approach, though:
function replacer(search, replace) {
var sel = window.getSelection();
if (!sel.focusNode) {
return;
}
var startIndex = sel.focusNode.nodeValue.indexOf(search);
var endIndex = startIndex + search.length;
if (startIndex === -1) {
return;
}
var range = document.createRange();
range.setStart(sel.focusNode, startIndex);
range.setEnd(sel.focusNode, endIndex);
range.insertNode(document.createTextNode("bar"));
sel.removeAllRanges();
sel.addRange(range);
}
document.addEventListener("keypress", function() {
replacer("foo", "bar");
});
<div contenteditable="true" style="width: 600px; height: 300px;">Lorem ipsum dolor foo amet, consectetur adipiscing elit.</div>
Note: I only care for compatibility with Chrome.
Explain in code comment and console log.
See about selection
function replacer(search, replace) {
var sel = window.getSelection();
if (!sel.focusNode) {
return;
}
var startIndex = sel.focusNode.nodeValue.indexOf(search);
var endIndex = startIndex + search.length;
if (startIndex === -1) {
return;
}
console.log("first focus node: ", sel.focusNode.nodeValue);
var range = document.createRange();
//Set the range to contain search text
range.setStart(sel.focusNode, startIndex);
range.setEnd(sel.focusNode, endIndex);
//Delete search text
range.deleteContents();
console.log("focus node after delete: ", sel.focusNode.nodeValue);
//Insert replace text
range.insertNode(document.createTextNode(replace));
console.log("focus node after insert: ", sel.focusNode.nodeValue);
//Move the caret to end of replace text
sel.collapse(sel.focusNode, 0);
}
document.addEventListener("keypress", function() {
replacer("foo", "bar");
});
<div contenteditable="true" style="width: 600px; height: 300px;" id='content'>Lorem ipsum dolor foo amet, consectetur adipiscing elit.</div>