Building an editor like below-- I need the user to be able to select some text but then use the input to do something without losing the selection.
function doReplace(){
const s = document.getSelection()
if(s?.anchorNode.parentElement.id != "out")return;
console.log('replace')
out.innerText = out.innerText.substring(0,s.anchorOffset) (inp.value||'FALLBACK') out.innerText.substring(s.extentOffset)
}
<input id="inp" placeholder="replace selection to" >
<button onclick="doReplace()">replace</button>
<p id="out">select some here and replace</p>
This demo reproduces the issue: one cannot use the input without losing their text selection.
How to input without changing focus?
A real world use case would be something like setting the font-size for the selection.
EDIT
Maybe cache selection is the way to go, but will loosing visual indication, trying to restore selection will lost focus again.
let s
function doReplace() {
if (s?.anchorNode?.parentElement.id != "out") return;
console.log('replace')
out.innerText = out.innerText.substring(0, s.anchorOffset) (inp.value || 'FALLBACK') out.innerText.substring(s.extentOffset)
}
function doRestore() {
if (s?.anchorNode?.parentElement.id != "out") return;
const sel = document.getSelection();
sel.setBaseAndExtent(s.anchorNode, s.anchorOffset, s.anchorNode, s.extentOffset);
}
out.addEventListener('mouseup', () => {
const sel = document.getSelection()
if(!sel)return;
const {
anchorNode,
anchorOffset,
extentOffset
} = sel || {}
s = {
text: sel.toString(),
anchorNode,
anchorOffset,
extentOffset
}
console.log(`sel`, s.anchorOffset, s.extentOffset, s.text)
}, false);
<input id="inp" placeholder="replace selection to" autocomplete="false" onfocus="doRestore()">
<button onclick="doReplace()">replace</button>
<p id="out">select some here and replace</p>
CodePudding user response:
Correct me if I'm wrong but I don't see a way of this being possible. the input/textarea tags require focus so the user will be able to type.
I recommend you use an EventListener instead of an input tag:
function doReplace(){
const s = document.getSelection()
if(s?.anchorNode.parentElement.id != "out")return;
console.log('replace')
out.innerText = out.innerText.substring(0,s.anchorOffset) (inp.value||'FALLBACK') out.innerText.substring(s.extentOffset)
}
window.addEventListener("keydown", event => {
document.getElementById("field").innerHTML = event.key
});
<div id="field"></div>
<button onclick="doReplace()">replace</button>
<p id="out">select some here and replace</p>