returning element altered by outerHTML
Asked Answered
S

1

7

I create a generic element by

var element = document.createElement(null);
document.body.appendChild(element);

after which, the element is altered by using outerHTML

element.outerHTML = "<div> hello there </div>";

the element displays correctly. However, the variable itself "element" does not reflect the alteration in any way. The only way to retrieve that particular element, seems to be doing something like...

element.outerHTML = "<div id='hi'> hello there </div>";
element = document.getElementById("hi");

Looks ugly. Is there any better way and/or am I missing something?

Synthesize answered 31/1, 2017 at 8:44 Comment(1)
We've got a quite new replaceWith method, and the ol'good replaceChild which would probably be cleaner. (wrap your new element in an off-doc div, set its innerHTML to the wanted one, then replace your old <null> with the off-doc div's content.Decasyllable
G
5

Consider the snippet below:

var element = document.createElement(null);
console.log(element);
document.body.appendChild(element);
console.log(element);
element.outerHTML = "<div id='hi'> hello there </div>";
console.log(element);
element = document.getElementById("hi");
console.log(element);

What you'll notice is that the reference is to the original element, after outerHTML is used. This is as stated in the documentation:

Also, while the element will be replaced in the document, the variable whose outerHTML property was set will still hold a reference to the original element.

Thus, the easiest way is to actually use document.getElementById() after setting said id to get the new element that was created or using document.createElement() like this to create a less generic object and manipulating its innerHTML():

var element = document.createElement('div');
console.log(element);
element.innerHTML = ' hello there ';
document.body.appendChild(element);
console.log(element);

As you can see, in the above snippet, element is the same after changing its content.

Update:

Using some creative trickery, you can add the stuff you want using innerHTML to the generic element you create, then grab its firstChild and replace element, then finally add it to your document and keep it selected. The example below shows you how to do this:

var element = document.createElement(null);
element.innerHTML = '<div> hello there </div>';
element = element.firstChild;
document.body.appendChild(element);
console.log(element);
Grassquit answered 31/1, 2017 at 8:53 Comment(7)
@Quentin you are right, I originally did not provide a better solution, so I updated my answer with one. Sorry for the delay!Grassquit
Thanks. Of course using innerHTML is easier and to some extent more elegant. However, I have several scenarios in which wrapping anything around the html I am injecting, will cause layout issues. To be more specific, all my HTML snippets already contain a <div class="something">....</div>, and using innerHTML would get me to <div><div class="something">....</div></div>Synthesize
@Synthesize I think that what you just explained is part of the bigger picture needed to solve the problem. Could you describe what you are trying to accomplish in a simple way? Are you trying to alter the content of existing elements or trying to add new elements?Grassquit
I have a library of elements, call them "templates" if you wish, stored in strings. I need to write a function that takes one of such templates (example <div class="blabla">...</div>), creates a new element based on this string, attaches it to the DOM and returns the element for further operationsSynthesize
@Synthesize So you want to use a template as-is, without wrapping it in another element, right?Grassquit
yes, which leads me to outerHTML. But now I am coming to understand that /obviously/ the node altered by outerHTML gets removed and replaced. Because the html could countain multiple nodes. So I think I am just on the wrong track.Synthesize
cunning, thanks. However, it should be element = element.firstElementChild;Synthesize

© 2022 - 2024 — McMap. All rights reserved.