替换输入 DOM 节点,同时保持焦点



我有一个普通的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 子树,浏览器没有神奇的方法可以"保留"焦点,因此您必须手动执行此操作。

最新更新