Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Replace an input DOM node while keeping focus

I have a normal HTML input box: <input id=​"ip">.

And this input box has focused. I know this by looking at the screen and the fact document.activeElement tells me so.

Now I want to replace this input node. And I do so with: var the_new_node = document.createElement("input"); the_new_node.id="ip"; the_input_node.replaceWith(the_new_node);

When I do this, however, the input box loses focus. document.activeElement now points to the body. Is there anyway to prevent this?

Edit: I realise I can call .focus(). Yet in my code I won't necessarily know if the node to be replaced will have an input within it.

For instance, the in various 'virtual dom' implementations they replace segments of the dom tree while retaining focus. How do they do it?

like image 247
mmm111mmm Avatar asked Oct 19 '25 10:10

mmm111mmm


1 Answers

If you want to only focus the new input if the element you're replacing had a focused element inside, you can code exactly that using .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>

There's no magic way the browser can "preserve" focus in face of replacing an arbitrary DOM sub-tree with another arbitrary sub-tree, so you have to do it manually.

like image 167
Nickolay Avatar answered Oct 22 '25 01:10

Nickolay



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!