如何在不改变焦点的情况下输入
How to input without change focus
构建如下所示的编辑器——我需要用户能够 select 一些文本,然后使用输入做一些事情而不丢失 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>
此演示重现了该问题:无法在不丢失文本的情况下使用输入 selection。
如何在不改变焦点的情况下输入?
真实世界的用例类似于为 selection 设置字体大小。
编辑
也许缓存 selection 是可行的方法,但会失去视觉指示,尝试恢复 selection 将再次失去焦点。
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>
如果我错了请纠正我,但我看不出有什么可能。 input/textarea 标签需要焦点,以便用户能够输入。
我建议您使用 EventListener 而不是输入标签:
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>
构建如下所示的编辑器——我需要用户能够 select 一些文本,然后使用输入做一些事情而不丢失 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>
此演示重现了该问题:无法在不丢失文本的情况下使用输入 selection。
如何在不改变焦点的情况下输入?
真实世界的用例类似于为 selection 设置字体大小。
编辑
也许缓存 selection 是可行的方法,但会失去视觉指示,尝试恢复 selection 将再次失去焦点。
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>
如果我错了请纠正我,但我看不出有什么可能。 input/textarea 标签需要焦点,以便用户能够输入。
我建议您使用 EventListener 而不是输入标签:
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>