我有一个普通的HTML输入框:<input id="ip">
.
这个输入框已经聚焦。我通过看屏幕知道这一点,document.activeElement
告诉我的事实告诉我。
现在我想替换这个输入节点。我这样做是:var the_new_node = document.createElement("input"); the_new_node.id="ip"; the_input_node.replaceWith(the_new_node);
但是,当我这样做时,输入框会失去焦点。 document.activeElement
现在指向身体。有没有办法防止这种情况?
编辑:我意识到我可以打电话给.focus()
。然而,在我的代码中,我不一定知道要替换的节点中是否有input
。
例如,在各种"虚拟 dom"实现中,它们替换了 dom 树的段,同时保留了焦点。他们是怎么做到的?
如果要替换的元素内部有一个聚焦元素,则只想聚焦新输入,则可以使用 .contains(document.activeElement)
进行精确编码:
function runReplace(idx) {
document.querySelectorAll("input")[0].focus();
setTimeout(() => {
let p = document.getElementById("par").children[idx];
let wasFocused = p.contains(document.activeElement);
let newNode = document.createElement("input");
newNode.type = "text";
newNode.value = "replacement for child #" + idx;
p.replaceWith(newNode);
if (wasFocused)
newNode.focus();
console.log("Replaced ", p, " with an input; wasFocused=", wasFocused);
}, 3000);
}
<div id="par">
<p>This is a paragraph with <b>an <input type="text" id="inp" value="<input>"> inside</b></p>
<p>This is a paragraph with no input inside</p>
</div>
<button onclick="runReplace(0)">Replace first paragraph in 3 seconds</button>
<button onclick="runReplace(1)">Replace second paragraph in 3 seconds</button>
面对用另一个任意子树替换任意 DOM 子树,浏览器没有神奇的方法可以"保留"焦点,因此您必须手动执行此操作。