What would be an efficient way to replace a DOM node with an array of nodes
(which are a simple array of detached nodes and not HTMLCollection)
(please no jQuery answers)
Demo page
HTML
<body>
<header>
<div>foo</div>
<div>bar</div>
</header>
</body>
JS
// generate simple dummy array of detached DOM nodes
var link1 = document.createElement('a');
link1.innerHTML = 'xxx';
var link2 = document.createElement('a');
link2.innerHTML = 'yyy';
var nodesArr = [link1, link2];
// get the element to replace at some place in the DOM.
// in the case, the second <div> inside the <header> element
var nodeToReplace = document.querySelectorAll('header > div')[1];
// replace "nodeToReplace" with "nodesArr"
for(let node of nodesArr)
nodeToReplace.parentNode.insertBefore(node, nodeToReplace);
nodeToReplace.parentNode.removeChild(nodeToReplace);
What would be an efficient way to replace a DOM node with an array of nodes
(which are a simple array of detached nodes and not HTMLCollection)
(please no jQuery answers)
Demo page
HTML
<body>
<header>
<div>foo</div>
<div>bar</div>
</header>
</body>
JS
// generate simple dummy array of detached DOM nodes
var link1 = document.createElement('a');
link1.innerHTML = 'xxx';
var link2 = document.createElement('a');
link2.innerHTML = 'yyy';
var nodesArr = [link1, link2];
// get the element to replace at some place in the DOM.
// in the case, the second <div> inside the <header> element
var nodeToReplace = document.querySelectorAll('header > div')[1];
// replace "nodeToReplace" with "nodesArr"
for(let node of nodesArr)
nodeToReplace.parentNode.insertBefore(node, nodeToReplace);
nodeToReplace.parentNode.removeChild(nodeToReplace);
Share
Improve this question
edited Sep 12, 2016 at 20:10
vsync
asked Sep 12, 2016 at 14:20
vsyncvsync
131k59 gold badges340 silver badges423 bronze badges
6
- Did you find a way that works but you consider inefficient? – Bergi Commented Sep 12, 2016 at 14:26
- Would simply iterating over the array not be a passable solution? – DBS Commented Sep 12, 2016 at 14:27
- Why do you emphasise "and not HTMLCollection"? Would there be anything different? – Bergi Commented Sep 12, 2016 at 14:28
- @Bergi - just to making sure it's a real Array and not another else, such as an HTMLCollection. also, I know of ways ofc, such as iteration, but I'm trying to find a sleek way maybe with some esoteric DOM method or some clever way. – vsync Commented Sep 12, 2016 at 14:31
- @DBS - iterating the array would be the most straight-forward approach but will result in quite a lot of code, and i'm trying to find a better approach than that, if exists. seems like the DOM API should have had a solution for such scenario. – vsync Commented Sep 12, 2016 at 14:33
2 Answers
Reset to default 9You can use a DocumentFragment
instead of the array:
var nodesFragment = document.createDocumentFragment();
nodesFragment.appendChild(link1);
nodesFragment.appendChild(link2);
nodeToReplace.replaceWith(nodesFragment); // experimental, no good browser support
nodeToReplace.parentNode.replaceChild(nodesFragment, nodeToReplace); // standard
However, just inserting multiple elements in a loop shouldn't be much different with regard to performance. Building a document fragment from an existing array might even be slower.
My initial solution was a straightforward iteration:
// iterate on the Array and insert each element before the one to be removed
for(let node of nodesArr)
nodeToReplace.parentNode.insertBefore(node, nodeToReplace);
// remove the chosen element
nodeToReplace.parentNode.removeChild(nodeToReplace);