Reputation: 647
I'm trying to automate calling a function (initBox) on all elements with class box on the page in vanilla javascript. I have made a functional solution except that it only applies to elements that are on the page when it is loaded. If I add an element to the DOM using javascript, the function (initBox) is not called on it.
Of course I can call the function (initBox) manually after adding the element, but I would like to automate it.
I'm looking for something similar to what jQuery does for events.
For example:
$('table').on('click', 'td', function (event) {
doSomething();
});
This event is called even if I add the TD element to the table later via javascript.
Here is my current solution:
function addBox() {
var btn = document.getElementsByTagName('button')[0];
var el = document.createElement('div');
el.classList.add('box');
el.innerText = (document.getElementsByTagName('div').length + 1);
btn.before(el);
}
function initBox(el) {
el.innerText += ' Initialized';
}
document.querySelectorAll('.box').forEach(initBox);
.box {
display: inline-block;
border: 1px solid #1f2227;
padding: 20px;
}
button {
padding: 20px;
}
<div class="box">1</div>
<div class="box">2</div>
<button onclick="addBox()">Add box</button>
Upvotes: 0
Views: 226
Reputation: 13432
The OP's problem can be solved just by the usage of a MutationObserver
instance where the OP needs the callback from the list off added nodes just to initialize the very nodes which do match the OP's definition of a box
.
function addBox() {
var btn = document.getElementsByTagName('button')[0];
var el = document.createElement('div');
el.classList.add('box');
el.innerText = (document.getElementsByTagName('div').length + 1);
btn.before(el);
}
function initBox(el) {
el.innerText += ' Initialized';
}
document.querySelectorAll('.box').forEach(initBox);
function initializeBoxClassDivOnly(node) {
if (node.nodeType === 1 && node.matches('div.box')) {
initBox(node);
}
}
function handleNodeInsertion(mutationList/*, observer*/) {
for (const mutation of mutationList) {
mutation
.addedNodes
.forEach(initializeBoxClassDivOnly);
}
};
const observer = new MutationObserver(handleNodeInsertion);
observer
.observe(document.body, { childList: true, subtree: true });
.box {
display: inline-block;
border: 1px solid #1f2227;
padding: 20px;
}
button {
padding: 20px;
}
<div class="box">1</div>
<div class="box">2</div>
<button onclick="addBox()">Add box</button>
Upvotes: 1
Reputation: 35
Look Into Mutation Observers, they are the new way of observing dom objects, it allows you to run a function when an item is added or removed or modified in a particular DOM element, or if you want you can go old school ( meaning you add event listeners).
Mutation Observers ( Recommended Method ) https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver
Old School Evens https://developer.mozilla.org/en-US/docs/Web/API/MutationEvent
if you want me to write the code, let me know in the comments.
Upvotes: 0