I'm using native javascript to append an element to my DOM, which disappears after X seconds.
To append the element I create a document fragment with a function createHTML
I then append this element to my container element.
var elementHTML = '<div>Test element appended</div>';
elementHTML = createHTML(elementHTML);
document.getElementById('append-container').appendChild(elementHTML);
I then set a timeout that removes the element from the DOM after x seconds
setTimeout(function() {
elementHTML.parentNode.removeChild(elementHTML);
}, 2000, elementHTML);
Now this won't work because when you use appendChild, the elements get moved and the reference to the element is lost. I'm looking for a way to update the reference for elementHTML
to the element I just appended to the DOM.
Basically I'm looking for the jQuery reference funcionality without using jQuery.
I could use a randomly generated ID to target the element or add a class and loop trough all the elements with that class and target the last one, but these methods feel ugly.
I'm wondering if there is some sort of callback when you append something to the DOM to target what you just appended or if my logic in going about this is just plain wrong.
FIDDLE
The issue is that a DocumentFragment
will move the contents of the fragment into the new place in the DOM, but the fragment itself will remain a fragment, not directly attached to anything:
https://developer.mozilla.org/en-US/docs/Web/API/Node/appendChild
If the given child is a DocumentFragment, the entire contents of the DocumentFragment are moved into the child list of the specified parent node.
After all, otherwise, if the HTML string is
<div>Test element appended</div><div>Test element 2 appended</div>
what could the appended documentFragment
refer to? It's couldn't be just one or the other <div>
, nor could it be the parent element (which was already in the DOM, and was not created with the fragment).
So, once a documentFragment
is appended, it cannot be removed all in one go.
If the fragment is guaranteed to contain only one element, like in your example, then select that one element and append it instead (and then you can properly reference its parentNode
).
// though using a documentFragment in the first place is a bit odd
// if you're not going to append it
var createHTML = function(htmlStr) {
var frag = document.createDocumentFragment(),
temp = document.createElement('div');
temp.innerHTML = htmlStr;
while (temp.firstChild) {
frag.appendChild(temp.firstChild);
}
return frag;
}
var appendItems = function() {
const elementHTML = '<div>Test element appended</div>';
const fragment = createHTML(elementHTML);
const fragmentElm = fragment.children[0];
document.getElementById('append-container').appendChild(fragmentElm);
setTimeout(function() {
fragmentElm.parentNode.removeChild(fragmentElm);
}, 2000, elementHTML);
}
document.getElementById('test-append').addEventListener('click', appendItems);
<div id="append-container">
</div>
<button id="test-append">
Test
</button>
Another option is to iterate through all appended nodes and .remove()
them:
var createHTML = function(htmlStr) {
var frag = document.createDocumentFragment(),
temp = document.createElement('div');
temp.innerHTML = htmlStr;
while (temp.firstChild) {
frag.appendChild(temp.firstChild);
}
return frag;
}
var appendItems = function() {
const elementHTML = '<div>Test element appended</div><div>Test element 2 appended</div>';
const fragment = createHTML(elementHTML);
const fragmentElms = [...fragment.children];
const container = document.getElementById('append-container');
fragmentElms.forEach((elm) => {
container.appendChild(elm);
});
setTimeout(function() {
fragmentElms.forEach((elm) => {
elm.remove();
});
}, 2000, elementHTML);
}
document.getElementById('test-append').addEventListener('click', appendItems);
<div id="append-container">
</div>
<button id="test-append">
Test
</button>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With