0

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>
Peter Seliger
  • 11,747
  • 3
  • 28
  • 37
Earlgray
  • 647
  • 1
  • 8
  • 31
  • Do you want that function to be called on click on all `.box` elements? – Rajesh Jan 06 '23 at 07:59
  • No, that was just an example of how it works in jQuery – Earlgray Jan 06 '23 at 08:47
  • The OP's chosen jQuery example is misleading since the technique behind is [event delegation](https://davidwalsh.name/event-delegate) whereas the OP's problem can be solved just by the usage of a [`MutationObserver`](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver). Please remove that part of the problem's description. – Peter Seliger Jan 06 '23 at 11:02

2 Answers2

1

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>
Peter Seliger
  • 11,747
  • 3
  • 28
  • 37
0

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.